diff --git a/Makefile b/Makefile index 91b10876dae..ddc2dcd4408 100644 --- a/Makefile +++ b/Makefile @@ -76,7 +76,6 @@ DIRECT_TESTS += \ cpp_pulse-11 \ cpp_pulse-17 \ cpp_pulse-20 \ - cpp_quandary \ cpp_racerd \ cpp_siof \ cpp_starvation \ @@ -150,7 +149,6 @@ DIRECT_TESTS += \ objc_performance \ objc_pulse \ objc_pulse-data-lineage \ - objc_quandary \ objc_self-in-block \ objcpp_biabduction \ objcpp_frontend \ @@ -258,7 +256,6 @@ DIRECT_TESTS += \ java_performance-exclusive \ java_pulse \ java_purity \ - java_quandary \ java_racerd \ java_scopeleakage \ java_sil \ diff --git a/infer/documentation/checkers/Quandary.md b/infer/documentation/checkers/Quandary.md deleted file mode 100644 index 28ed647eb99..00000000000 --- a/infer/documentation/checkers/Quandary.md +++ /dev/null @@ -1,8 +0,0 @@ -Quandary is a static taint analyzer that identifies a variety of unsafe -information flows. It has a small list of built-in -[sources](https://github.com/facebook/infer/blob/main/infer/src/quandary/JavaTrace.ml#L36) -and -[sinks](https://github.com/facebook/infer/blob/main/infer/src/quandary/JavaTrace.ml#L178), -and you can define custom sources and sinks in your `.inferconfig` file (see -example -[here](https://github.com/facebook/infer/blob/main/infer/tests/codetoanalyze/java/quandary/.inferconfig)). diff --git a/infer/man/man1/infer-analyze.txt b/infer/man/man1/infer-analyze.txt index 10dd660cc9f..fe855364d1e 100644 --- a/infer/man/man1/infer-analyze.txt +++ b/infer/man/man1/infer-analyze.txt @@ -328,20 +328,6 @@ OPTIONS --qualified-cpp-name-block-list +string Skip analyzing the procedures under the qualified cpp type name. - --quandary - Activates: quandary checker: The Quandary taint analysis detects - flows of values between sources and sinks, except if the value - went through a "sanitizer". In addition to some defaults, users - can specify their own sources, sinks, and sanitizers functions. - - DEPRECATED: Taint analysis is now supported by the Pulse checker - and Quandary will be removed in the next release. - (Conversely: --no-quandary) - - --quandary-only - Activates: Enable quandary and disable all other checkers - (Conversely: --no-quandary-only) - --quiet,-q Activates: Do not print anything on standard output. (Conversely: --no-quiet | -Q) @@ -1047,19 +1033,6 @@ PULSE CHECKER OPTIONS --pulse-widen-threshold int Stop exploring new paths after int loop iterations -QUANDARY CHECKER OPTIONS - --quandary-endpoints json - Specify endpoint classes for Quandary - - --quandary-sanitizers json - Specify custom sanitizers for Quandary - - --quandary-sinks json - Specify custom sinks for Quandary - - --quandary-sources json - Specify custom sources for Quandary - RACERD CHECKER OPTIONS --racerd-always-report-java Activates: Every Java class analysed is treated as if it were diff --git a/infer/man/man1/infer-full.txt b/infer/man/man1/infer-full.txt index 8eae5b80acc..61db3860b23 100644 --- a/infer/man/man1/infer-full.txt +++ b/infer/man/man1/infer-full.txt @@ -621,8 +621,6 @@ OPTIONS CONFIG_USAGE (disabled by default), CONSTANT_ADDRESS_DEREFERENCE (disabled by default), CONSTANT_ADDRESS_DEREFERENCE_LATENT (disabled by default), - CREATE_INTENT_FROM_URI (enabled by default), - CROSS_SITE_SCRIPTING (enabled by default), CXX_REF_CAPTURED_IN_BLOCK (enabled by default), Cannot_star (enabled by default), DANGLING_POINTER_DEREFERENCE (disabled by default), @@ -640,7 +638,6 @@ OPTIONS EXECUTION_TIME_UNREACHABLE_AT_EXIT (disabled by default), EXPENSIVE_EXECUTION_TIME (disabled by default), EXPENSIVE_LOOP_INVARIANT_CALL (enabled by default), - EXPOSED_INSECURE_INTENT_HANDLING (enabled by default), Failure_exe (enabled by default), GUARDEDBY_VIOLATION (enabled by default), IMPURE_FUNCTION (enabled by default), @@ -652,7 +649,6 @@ OPTIONS INFERBO_ALLOC_MAY_BE_NEGATIVE (enabled by default), INFINITE_EXECUTION_TIME (disabled by default), INHERENTLY_DANGEROUS_FUNCTION (enabled by default), - INSECURE_INTENT_HANDLING (enabled by default), INTEGER_OVERFLOW_L1 (enabled by default), INTEGER_OVERFLOW_L2 (enabled by default), INTEGER_OVERFLOW_L5 (disabled by default), @@ -662,11 +658,9 @@ OPTIONS INVARIANT_CALL (disabled by default), IPC_ON_UI_THREAD (enabled by default), Internal_error (enabled by default), - JAVASCRIPT_INJECTION (enabled by default), LAB_RESOURCE_LEAK (enabled by default), LOCKLESS_VIOLATION (enabled by default), LOCK_CONSISTENCY_VIOLATION (enabled by default), - LOGGING_PRIVATE_DATA (enabled by default), Leak_after_array_abstraction (enabled by default), Leak_in_footprint (enabled by default), Leak_unknown_origin (disabled by default), @@ -732,18 +726,13 @@ OPTIONS PULSE_UNNECESSARY_COPY_OPTIONAL_CONST (disabled by default), PULSE_UNNECESSARY_COPY_RETURN (disabled by default), PURE_FUNCTION (enabled by default), - QUANDARY_TAINT_ERROR (enabled by default), REGEX_OP_ON_UI_THREAD (enabled by default), RESOURCE_LEAK (enabled by default), RETAIN_CYCLE (enabled by default), RETAIN_CYCLE_NO_WEAK_INFO (disabled by default), SCOPE_LEAKAGE (enabled by default), SENSITIVE_DATA_FLOW (disabled by default), - SHELL_INJECTION (enabled by default), - SHELL_INJECTION_RISK (enabled by default), SKIP_FUNCTION (disabled by default), - SQL_INJECTION (enabled by default), - SQL_INJECTION_RISK (enabled by default), STACK_VARIABLE_ADDRESS_ESCAPE (enabled by default), STARVATION (enabled by default), STATIC_INITIALIZATION_ORDER_FIASCO (enabled by default), @@ -755,17 +744,6 @@ OPTIONS TOPL_ERROR (enabled by default), TOPL_ERROR_LATENT (disabled by default), UNREACHABLE_CODE (enabled by default), - UNTRUSTED_BUFFER_ACCESS (disabled by default), - UNTRUSTED_DESERIALIZATION (enabled by default), - UNTRUSTED_DESERIALIZATION_RISK (enabled by default), - UNTRUSTED_ENVIRONMENT_CHANGE_RISK (enabled by default), - UNTRUSTED_FILE (enabled by default), - UNTRUSTED_FILE_RISK (enabled by default), - UNTRUSTED_HEAP_ALLOCATION (disabled by default), - UNTRUSTED_INTENT_CREATION (enabled by default), - UNTRUSTED_URL_RISK (enabled by default), - UNTRUSTED_VARIABLE_LENGTH_ARRAY (enabled by default), - USER_CONTROLLED_SQL_RISK (enabled by default), USE_AFTER_DELETE (enabled by default), USE_AFTER_DELETE_LATENT (disabled by default), USE_AFTER_FREE (enabled by default), @@ -1842,38 +1820,6 @@ OPTIONS Skip analyzing the procedures under the qualified cpp type name. See also infer-analyze(1). - --quandary - Activates: quandary checker: The Quandary taint analysis detects - flows of values between sources and sinks, except if the value - went through a "sanitizer". In addition to some defaults, users - can specify their own sources, sinks, and sanitizers functions. - - DEPRECATED: Taint analysis is now supported by the Pulse checker - and Quandary will be removed in the next release. - (Conversely: --no-quandary) - See also infer-analyze(1). - - --quandary-endpoints json - Specify endpoint classes for Quandary - See also infer-analyze(1). - - --quandary-only - Activates: Enable quandary and disable all other checkers - (Conversely: --no-quandary-only) - See also infer-analyze(1). - - --quandary-sanitizers json - Specify custom sanitizers for Quandary - See also infer-analyze(1). - - --quandary-sinks json - Specify custom sinks for Quandary - See also infer-analyze(1). - - --quandary-sources json - Specify custom sources for Quandary - See also infer-analyze(1). - --quiet,-q Activates: Do not print anything on standard output. (Conversely: --no-quiet | -Q) @@ -3221,12 +3167,6 @@ INTERNAL OPTIONS --qualified-cpp-name-block-list-reset Set --qualified-cpp-name-block-list to the empty list. - --quandary-show-passthroughs - Activates: In error traces, show intermediate steps that propagate - data. When false, error traces are shorter and show only direct - flow via souces/sinks (Conversely: - --no-quandary-show-passthroughs) - --racerd-ignore-classes-reset Set --racerd-ignore-classes to the empty list. diff --git a/infer/man/man1/infer-report.txt b/infer/man/man1/infer-report.txt index 91846c39da1..4ab1a246c0f 100644 --- a/infer/man/man1/infer-report.txt +++ b/infer/man/man1/infer-report.txt @@ -141,8 +141,6 @@ OPTIONS CONFIG_USAGE (disabled by default), CONSTANT_ADDRESS_DEREFERENCE (disabled by default), CONSTANT_ADDRESS_DEREFERENCE_LATENT (disabled by default), - CREATE_INTENT_FROM_URI (enabled by default), - CROSS_SITE_SCRIPTING (enabled by default), CXX_REF_CAPTURED_IN_BLOCK (enabled by default), Cannot_star (enabled by default), DANGLING_POINTER_DEREFERENCE (disabled by default), @@ -160,7 +158,6 @@ OPTIONS EXECUTION_TIME_UNREACHABLE_AT_EXIT (disabled by default), EXPENSIVE_EXECUTION_TIME (disabled by default), EXPENSIVE_LOOP_INVARIANT_CALL (enabled by default), - EXPOSED_INSECURE_INTENT_HANDLING (enabled by default), Failure_exe (enabled by default), GUARDEDBY_VIOLATION (enabled by default), IMPURE_FUNCTION (enabled by default), @@ -172,7 +169,6 @@ OPTIONS INFERBO_ALLOC_MAY_BE_NEGATIVE (enabled by default), INFINITE_EXECUTION_TIME (disabled by default), INHERENTLY_DANGEROUS_FUNCTION (enabled by default), - INSECURE_INTENT_HANDLING (enabled by default), INTEGER_OVERFLOW_L1 (enabled by default), INTEGER_OVERFLOW_L2 (enabled by default), INTEGER_OVERFLOW_L5 (disabled by default), @@ -182,11 +178,9 @@ OPTIONS INVARIANT_CALL (disabled by default), IPC_ON_UI_THREAD (enabled by default), Internal_error (enabled by default), - JAVASCRIPT_INJECTION (enabled by default), LAB_RESOURCE_LEAK (enabled by default), LOCKLESS_VIOLATION (enabled by default), LOCK_CONSISTENCY_VIOLATION (enabled by default), - LOGGING_PRIVATE_DATA (enabled by default), Leak_after_array_abstraction (enabled by default), Leak_in_footprint (enabled by default), Leak_unknown_origin (disabled by default), @@ -252,18 +246,13 @@ OPTIONS PULSE_UNNECESSARY_COPY_OPTIONAL_CONST (disabled by default), PULSE_UNNECESSARY_COPY_RETURN (disabled by default), PURE_FUNCTION (enabled by default), - QUANDARY_TAINT_ERROR (enabled by default), REGEX_OP_ON_UI_THREAD (enabled by default), RESOURCE_LEAK (enabled by default), RETAIN_CYCLE (enabled by default), RETAIN_CYCLE_NO_WEAK_INFO (disabled by default), SCOPE_LEAKAGE (enabled by default), SENSITIVE_DATA_FLOW (disabled by default), - SHELL_INJECTION (enabled by default), - SHELL_INJECTION_RISK (enabled by default), SKIP_FUNCTION (disabled by default), - SQL_INJECTION (enabled by default), - SQL_INJECTION_RISK (enabled by default), STACK_VARIABLE_ADDRESS_ESCAPE (enabled by default), STARVATION (enabled by default), STATIC_INITIALIZATION_ORDER_FIASCO (enabled by default), @@ -275,17 +264,6 @@ OPTIONS TOPL_ERROR (enabled by default), TOPL_ERROR_LATENT (disabled by default), UNREACHABLE_CODE (enabled by default), - UNTRUSTED_BUFFER_ACCESS (disabled by default), - UNTRUSTED_DESERIALIZATION (enabled by default), - UNTRUSTED_DESERIALIZATION_RISK (enabled by default), - UNTRUSTED_ENVIRONMENT_CHANGE_RISK (enabled by default), - UNTRUSTED_FILE (enabled by default), - UNTRUSTED_FILE_RISK (enabled by default), - UNTRUSTED_HEAP_ALLOCATION (disabled by default), - UNTRUSTED_INTENT_CREATION (enabled by default), - UNTRUSTED_URL_RISK (enabled by default), - UNTRUSTED_VARIABLE_LENGTH_ARRAY (enabled by default), - USER_CONTROLLED_SQL_RISK (enabled by default), USE_AFTER_DELETE (enabled by default), USE_AFTER_DELETE_LATENT (disabled by default), USE_AFTER_FREE (enabled by default), diff --git a/infer/man/man1/infer.txt b/infer/man/man1/infer.txt index 4cd6a8ae963..5736f7150d2 100644 --- a/infer/man/man1/infer.txt +++ b/infer/man/man1/infer.txt @@ -621,8 +621,6 @@ OPTIONS CONFIG_USAGE (disabled by default), CONSTANT_ADDRESS_DEREFERENCE (disabled by default), CONSTANT_ADDRESS_DEREFERENCE_LATENT (disabled by default), - CREATE_INTENT_FROM_URI (enabled by default), - CROSS_SITE_SCRIPTING (enabled by default), CXX_REF_CAPTURED_IN_BLOCK (enabled by default), Cannot_star (enabled by default), DANGLING_POINTER_DEREFERENCE (disabled by default), @@ -640,7 +638,6 @@ OPTIONS EXECUTION_TIME_UNREACHABLE_AT_EXIT (disabled by default), EXPENSIVE_EXECUTION_TIME (disabled by default), EXPENSIVE_LOOP_INVARIANT_CALL (enabled by default), - EXPOSED_INSECURE_INTENT_HANDLING (enabled by default), Failure_exe (enabled by default), GUARDEDBY_VIOLATION (enabled by default), IMPURE_FUNCTION (enabled by default), @@ -652,7 +649,6 @@ OPTIONS INFERBO_ALLOC_MAY_BE_NEGATIVE (enabled by default), INFINITE_EXECUTION_TIME (disabled by default), INHERENTLY_DANGEROUS_FUNCTION (enabled by default), - INSECURE_INTENT_HANDLING (enabled by default), INTEGER_OVERFLOW_L1 (enabled by default), INTEGER_OVERFLOW_L2 (enabled by default), INTEGER_OVERFLOW_L5 (disabled by default), @@ -662,11 +658,9 @@ OPTIONS INVARIANT_CALL (disabled by default), IPC_ON_UI_THREAD (enabled by default), Internal_error (enabled by default), - JAVASCRIPT_INJECTION (enabled by default), LAB_RESOURCE_LEAK (enabled by default), LOCKLESS_VIOLATION (enabled by default), LOCK_CONSISTENCY_VIOLATION (enabled by default), - LOGGING_PRIVATE_DATA (enabled by default), Leak_after_array_abstraction (enabled by default), Leak_in_footprint (enabled by default), Leak_unknown_origin (disabled by default), @@ -732,18 +726,13 @@ OPTIONS PULSE_UNNECESSARY_COPY_OPTIONAL_CONST (disabled by default), PULSE_UNNECESSARY_COPY_RETURN (disabled by default), PURE_FUNCTION (enabled by default), - QUANDARY_TAINT_ERROR (enabled by default), REGEX_OP_ON_UI_THREAD (enabled by default), RESOURCE_LEAK (enabled by default), RETAIN_CYCLE (enabled by default), RETAIN_CYCLE_NO_WEAK_INFO (disabled by default), SCOPE_LEAKAGE (enabled by default), SENSITIVE_DATA_FLOW (disabled by default), - SHELL_INJECTION (enabled by default), - SHELL_INJECTION_RISK (enabled by default), SKIP_FUNCTION (disabled by default), - SQL_INJECTION (enabled by default), - SQL_INJECTION_RISK (enabled by default), STACK_VARIABLE_ADDRESS_ESCAPE (enabled by default), STARVATION (enabled by default), STATIC_INITIALIZATION_ORDER_FIASCO (enabled by default), @@ -755,17 +744,6 @@ OPTIONS TOPL_ERROR (enabled by default), TOPL_ERROR_LATENT (disabled by default), UNREACHABLE_CODE (enabled by default), - UNTRUSTED_BUFFER_ACCESS (disabled by default), - UNTRUSTED_DESERIALIZATION (enabled by default), - UNTRUSTED_DESERIALIZATION_RISK (enabled by default), - UNTRUSTED_ENVIRONMENT_CHANGE_RISK (enabled by default), - UNTRUSTED_FILE (enabled by default), - UNTRUSTED_FILE_RISK (enabled by default), - UNTRUSTED_HEAP_ALLOCATION (disabled by default), - UNTRUSTED_INTENT_CREATION (enabled by default), - UNTRUSTED_URL_RISK (enabled by default), - UNTRUSTED_VARIABLE_LENGTH_ARRAY (enabled by default), - USER_CONTROLLED_SQL_RISK (enabled by default), USE_AFTER_DELETE (enabled by default), USE_AFTER_DELETE_LATENT (disabled by default), USE_AFTER_FREE (enabled by default), @@ -1842,38 +1820,6 @@ OPTIONS Skip analyzing the procedures under the qualified cpp type name. See also infer-analyze(1). - --quandary - Activates: quandary checker: The Quandary taint analysis detects - flows of values between sources and sinks, except if the value - went through a "sanitizer". In addition to some defaults, users - can specify their own sources, sinks, and sanitizers functions. - - DEPRECATED: Taint analysis is now supported by the Pulse checker - and Quandary will be removed in the next release. - (Conversely: --no-quandary) - See also infer-analyze(1). - - --quandary-endpoints json - Specify endpoint classes for Quandary - See also infer-analyze(1). - - --quandary-only - Activates: Enable quandary and disable all other checkers - (Conversely: --no-quandary-only) - See also infer-analyze(1). - - --quandary-sanitizers json - Specify custom sanitizers for Quandary - See also infer-analyze(1). - - --quandary-sinks json - Specify custom sinks for Quandary - See also infer-analyze(1). - - --quandary-sources json - Specify custom sources for Quandary - See also infer-analyze(1). - --quiet,-q Activates: Do not print anything on standard output. (Conversely: --no-quiet | -Q) diff --git a/infer/src/IR/BUILTINS.ml b/infer/src/IR/BUILTINS.ml index eefdc7028e1..0268bbb7a6f 100644 --- a/infer/src/IR/BUILTINS.ml +++ b/infer/src/IR/BUILTINS.ml @@ -11,8 +11,6 @@ open! IStd module type S = sig type t - val __array_access : t - val __assert_fail : t val __builtin_add_overflow : t @@ -50,8 +48,6 @@ module type S = sig val __get_type_of : t - val __global_access : t - val __infer_assume : t val __infer_fail : t diff --git a/infer/src/IR/BuiltinDecl.ml b/infer/src/IR/BuiltinDecl.ml index 704deca4343..00dd6aa7863 100644 --- a/infer/src/IR/BuiltinDecl.ml +++ b/infer/src/IR/BuiltinDecl.ml @@ -32,8 +32,6 @@ let create_objc_class_method class_name method_name parameters = let is_declared pname = Procname.Set.mem pname !builtin_decls -let __array_access = create_procname "__array_access" - let __assert_fail = create_procname "__assert_fail" let __atomic_fetch_max = create_procname "__atomic_fetch_max" @@ -156,8 +154,6 @@ let __get_hidden_field = create_procname "__get_hidden_field" let __get_type_of = create_procname "__get_type_of" -let __global_access = create_procname "__global_access" - let __infer_assume = create_procname "__infer_assume" let __infer_fail = create_procname "__infer_fail" diff --git a/infer/src/IR/Ident.ml b/infer/src/IR/Ident.ml index 16581bc9462..0515c33fd56 100644 --- a/infer/src/IR/Ident.ml +++ b/infer/src/IR/Ident.ml @@ -171,9 +171,6 @@ let create_fresh kind = NameGenerator.create_fresh_ident kind (standard_name kin let create_none () = create_fresh KNone -(** Generate a footprint identifier with the given name and stamp *) -let create_footprint name stamp = create_with_stamp KFootprint name stamp - (** {2 Functions for Identifiers} *) (** Get a name of an identifier *) diff --git a/infer/src/IR/Ident.mli b/infer/src/IR/Ident.mli index ef98b8f8356..af339af1107 100644 --- a/infer/src/IR/Ident.mli +++ b/infer/src/IR/Ident.mli @@ -86,9 +86,6 @@ val create_normal : name -> int -> t val create_none : unit -> t (** Create a "null" identifier for situations where the IR requires an id that will never be read *) -val create_footprint : name -> int -> t -(** Generate a footprint identifier with the given name and stamp. *) - val update_name_generator : t list -> unit (** Update the name generator so that the given id's are not generated again *) diff --git a/infer/src/IR/IntLit.mli b/infer/src/IR/IntLit.mli index 729b17c0efe..e883d529ae8 100644 --- a/infer/src/IR/IntLit.mli +++ b/infer/src/IR/IntLit.mli @@ -98,7 +98,7 @@ val max : t -> t -> t val min : t -> t -> t -val to_int : t -> int option +val to_int : t -> int option [@@warning "-unused-value-declaration"] val to_int_exn : t -> int diff --git a/infer/src/IR/Procdesc.mli b/infer/src/IR/Procdesc.mli index a8f8325f387..9db70731bbd 100644 --- a/infer/src/IR/Procdesc.mli +++ b/infer/src/IR/Procdesc.mli @@ -242,6 +242,7 @@ val from_proc_attributes : ProcAttributes.t -> t (** Use [Cfg.create_proc_desc] if you are adding a proc desc to a cfg *) val get_access : t -> ProcAttributes.access +[@@warning "-unused-value-declaration"] (** Return the visibility attribute *) val get_attributes : t -> ProcAttributes.t diff --git a/infer/src/IR/Procname.ml b/infer/src/IR/Procname.ml index 5c7d35a828b..7b1fc715b0a 100644 --- a/infer/src/IR/Procname.ml +++ b/infer/src/IR/Procname.ml @@ -252,16 +252,6 @@ module Java = struct let is_autogen_method {method_name} = JConfig.is_synthetic_name method_name - (** Check if the proc name has the type of a java vararg. Note: currently only checks that the - last argument has type Object[]. *) - let is_vararg {parameters} = - match List.last parameters with - | Some {desc= Tptr ({desc= Tarray {elt}}, Pk_pointer)} -> - Typ.equal StdTyp.Java.pointer_to_java_lang_object elt - | _ -> - false - - let is_external java_pname = let package = get_package java_pname in Option.exists ~f:Config.java_package_is_external package diff --git a/infer/src/IR/Procname.mli b/infer/src/IR/Procname.mli index 7f71758b0c6..1fa307d92a9 100644 --- a/infer/src/IR/Procname.mli +++ b/infer/src/IR/Procname.mli @@ -87,10 +87,6 @@ module Java : sig val is_static : t -> bool (** Check if the java procedure is static. *) - val is_vararg : t -> bool - (** Check if the proc name has the type of a java vararg. Note: currently only checks that the - last argument has type Object[]. *) - val is_generated : t -> bool (** Check if the proc name comes from generated code *) @@ -146,8 +142,6 @@ module ObjC_Cpp : sig Typ.Name.t -> string -> kind -> Typ.template_spec_info -> Parameter.clang_parameter list -> t (** Create an objc procedure name from a class_name and method_name. *) - val get_class_name : t -> string - val get_class_type_name : t -> Typ.Name.t [@@warning "-unused-value-declaration"] val get_class_qualifiers : t -> QualifiedCppName.t diff --git a/infer/src/IR/QualifiedCppName.mli b/infer/src/IR/QualifiedCppName.mli index 70378cc77c9..5c9881cda22 100644 --- a/infer/src/IR/QualifiedCppName.mli +++ b/infer/src/IR/QualifiedCppName.mli @@ -26,12 +26,6 @@ val append_qualifier : t -> qual:string -> t val extract_last : t -> (string * t) option (** returns last (innermost scope) qualifier and qualified name without last qualifier *) -val strip_template_args : t -> t -(** returns qualified name without template arguments. For example: - - - input: std::shared_ptr::shared_ptr - - output: std::shared_ptr::shared_ptr *) - val compare_name : t -> t -> int (** similar to compare, but compares only names, except template arguments *) diff --git a/infer/src/IR/Var.ml b/infer/src/IR/Var.ml index 61fbb675d2f..9eed9d05e03 100644 --- a/infer/src/IR/Var.ml +++ b/infer/src/IR/Var.ml @@ -27,8 +27,6 @@ let of_id id = LogicalVar id let of_pvar pvar = ProgramVar pvar -let of_formal_index formal_index = of_id (Ident.create_footprint Ident.name_spec formal_index) - let to_exp = function ProgramVar pvar -> Exp.Lvar pvar | LogicalVar id -> Exp.Var id let get_ident = function ProgramVar _ -> None | LogicalVar id -> Some id diff --git a/infer/src/IR/Var.mli b/infer/src/IR/Var.mli index a98848c7c3d..6ec885d0232 100644 --- a/infer/src/IR/Var.mli +++ b/infer/src/IR/Var.mli @@ -18,7 +18,7 @@ val of_id : Ident.t -> t val of_pvar : Pvar.t -> t -val of_formal_index : int -> t +(* val of_formal_index : int -> t *) (** Create a variable representing the ith formal of the current procedure *) val get_all_vars_in_exp : Exp.t -> t Sequence.t @@ -36,8 +36,6 @@ val is_global : t -> bool val is_return : t -> bool -val is_footprint : t -> bool - val is_none : t -> bool val is_this : t -> bool diff --git a/infer/src/Makefile b/infer/src/Makefile index 24b01c83f0d..26062d61207 100644 --- a/infer/src/Makefile +++ b/infer/src/Makefile @@ -154,7 +154,7 @@ $(INFER_BIN_ALIASES): Makefile $(BIN_DIR)/$(INFER_MAIN) $(QUIET)touch $@ roots:=Infer -clusters:=absint al atd backend base biabduction bufferoverrun checkers clang clang_stubs concurrency cost c_stubs datalog deadcode integration IR istd java labs dotnet llvm opensource pulse python quandary scripts test_determinator topl unit +clusters:=absint al atd backend base biabduction bufferoverrun checkers clang clang_stubs concurrency cost c_stubs datalog deadcode integration IR istd java labs dotnet llvm opensource pulse python scripts test_determinator topl unit ml_src_files:=$(shell find . -not -path "./*stubs*" -regex '\./[a-zA-Z].*\.ml\(i\)*') inc_flags:=$(foreach dir,$(shell find . -not -path './_build*' -type d),-I $(dir)) diff --git a/infer/src/absint/AccessPath.ml b/infer/src/absint/AccessPath.ml index 6f7667b6cf6..88f1bf073e9 100644 --- a/infer/src/absint/AccessPath.ml +++ b/infer/src/absint/AccessPath.ml @@ -49,52 +49,6 @@ module Raw = struct F.fprintf fmt "%a.%a" pp_base base pp_access_list accesses - let lookup_field_type_annot tenv base_typ field_name = - let lookup = Tenv.lookup tenv in - Struct.get_field_type_and_annotation ~lookup field_name base_typ - - - (* Get the type of an access, or None if the type cannot be determined *) - let get_access_type tenv base_typ = function - | FieldAccess field_name -> - Option.map (lookup_field_type_annot tenv base_typ field_name) ~f:fst - | ArrayAccess (array_typ, _) -> - Some array_typ - - - (* Extract the last access of the given access path together with its base type. - * Here the base type is defined to be the declaring class of the last accessed field, - * or the type of base if the access list is empty. - * For example: - * - for x.f.g, the base type of the last access is typ(f); - * - for x.f[][], the base type of the last access is typ(x); - * - for x, the base type of the last access is type(x) *) - let last_access_info ((_, base_typ), accesses) tenv = - let rec last_access_info_impl tenv base_typ = function - | [] -> - (Some base_typ, None) - | [last_access] -> - (Some base_typ, Some last_access) - | curr_access :: rest -> ( - match get_access_type tenv base_typ curr_access with - | Some access_typ -> - last_access_info_impl tenv access_typ rest - | None -> - (None, None) ) - in - last_access_info_impl tenv base_typ accesses - - - let get_typ ap tenv = - match last_access_info ap tenv with - | (Some _ as typ), None -> - typ - | Some base_typ, Some access -> - get_access_type tenv base_typ access - | _ -> - None - - let base_of_pvar pvar typ = (Var.of_pvar pvar, typ) let base_of_id id typ = (Var.of_id id, typ) @@ -144,18 +98,6 @@ module Abs = struct let extract = function Exact ap | Abstracted ap -> ap - let with_base base = function - | Exact (_, accesses) -> - Exact (base, accesses) - | Abstracted (_, accesses) -> - Abstracted (base, accesses) - - - let to_footprint formal_index access_path = - let _, base_typ = fst (extract access_path) in - with_base (Var.of_formal_index formal_index, base_typ) access_path - - let get_footprint_index_base base = match base with | Var.LogicalVar id, _ when Ident.is_footprint id -> diff --git a/infer/src/absint/AccessPath.mli b/infer/src/absint/AccessPath.mli index b401ba62cf0..449fd1e0414 100644 --- a/infer/src/absint/AccessPath.mli +++ b/infer/src/absint/AccessPath.mli @@ -19,23 +19,23 @@ type access = as (x, [f; g]) *) and t = base * access list [@@deriving compare, equal] -val get_typ : t -> Tenv.t -> Typ.t option -(** get the typ of the last access in the list of accesses if the list is non-empty, or the base if - the list is empty. that is, for x.f.g, return typ(g), and for x, return typ(x) *) - val base_of_pvar : Pvar.t -> Typ.t -> base (** create a base from a pvar *) val of_pvar : Pvar.t -> Typ.t -> t (** create an access path from a pvar *) +(* used in infer/src/labs/ *) val of_id : Ident.t -> Typ.t -> t +[@@warning "-unused-value-declaration"] (** create an access path from an ident *) val of_var : Var.t -> Typ.t -> t (** create an access path from a var *) +(* used in infer/src/labs/ *) val append : t -> access list -> t +[@@warning "-unused-value-declaration"] (** append new accesses to an existing access path; e.g., `append_access x.f [g, h]` produces `x.f.g.h` *) @@ -64,17 +64,10 @@ module Abs : sig val equal : t -> t -> bool - val to_footprint : int -> t -> t - (** replace the base var with a footprint variable rooted at formal index [formal_index] *) - val get_footprint_index_base : base -> int option (** return the formal index associated with the base of this access path if there is one, or None otherwise *) - val with_base : base -> t -> t - (** swap base of existing access path for [base_var] (e.g., `with_base_bvar x y.f.g` produces - `x.f.g` *) - val extract : t -> raw (** extract a raw access path from its wrapper *) diff --git a/infer/src/absint/AndroidFramework.ml b/infer/src/absint/AndroidFramework.ml index 9f9bd824f52..5157c412107 100644 --- a/infer/src/absint/AndroidFramework.ml +++ b/infer/src/absint/AndroidFramework.ml @@ -9,8 +9,6 @@ open! IStd (** Android lifecycle types and their lifecycle methods that are called by the framework *) -let drawable_prefix = "R$drawable" - let is_autocloseable tenv tname = PatternMatch.is_subtype_of_str tenv tname "java.lang.AutoCloseable" diff --git a/infer/src/absint/AndroidFramework.mli b/infer/src/absint/AndroidFramework.mli index 61cc05fa445..9bbd852b104 100644 --- a/infer/src/absint/AndroidFramework.mli +++ b/infer/src/absint/AndroidFramework.mli @@ -9,7 +9,7 @@ open! IStd (** Android lifecycle types and their lifecycle methods that are called by the framework *) -val drawable_prefix : string +(* val drawable_prefix : string *) (** prefix for Drawable fields in generated resources *) val is_autocloseable : Tenv.t -> Typ.Name.t -> bool diff --git a/infer/src/absint/FormalMap.ml b/infer/src/absint/FormalMap.ml index b18e0511e18..88c9b657d71 100644 --- a/infer/src/absint/FormalMap.ml +++ b/infer/src/absint/FormalMap.ml @@ -24,8 +24,6 @@ let make attrs = ~init:AccessPath.BaseMap.empty formals_with_nums -let empty = AccessPath.BaseMap.empty - let is_formal = AccessPath.BaseMap.mem let get_formal_index base t = AccessPath.BaseMap.find_opt base t diff --git a/infer/src/absint/FormalMap.mli b/infer/src/absint/FormalMap.mli index 5b7357f4988..ceac1841011 100644 --- a/infer/src/absint/FormalMap.mli +++ b/infer/src/absint/FormalMap.mli @@ -14,9 +14,6 @@ type t val make : ProcAttributes.t -> t (** create a formal map for the given procdesc *) -val empty : t -(** the empty formal map *) - val is_formal : AccessPath.base -> t -> bool (** return true if the given base var is a formal according to the given formal map *) diff --git a/infer/src/absint/HilExp.ml b/infer/src/absint/HilExp.ml index 7777f35e6df..a31fc4f2045 100644 --- a/infer/src/absint/HilExp.ml +++ b/infer/src/absint/HilExp.ml @@ -348,43 +348,6 @@ module AccessExpression = struct let is_return_var = function Base (var, _) -> Var.is_return var | _ -> false end -let rec get_typ tenv = function - | AccessExpression access_expr -> - AccessExpression.get_typ access_expr tenv - | UnaryOperator (_, _, typ_opt) -> - typ_opt - | BinaryOperator ((Lt | Gt | Le | Ge | Eq | Ne | LAnd | LOr), _, _) -> - Some (Typ.mk (Typ.Tint Typ.IBool)) - | BinaryOperator (_, e1, e2) -> ( - (* TODO: doing this properly will require taking account of language-specific coercion - semantics. Only return a type when the operands have the same type for now *) - match (get_typ tenv e1, get_typ tenv e2) with - | Some typ1, Some typ2 when Typ.equal typ1 typ2 -> - Some typ1 - | _ -> - None ) - | Exception t -> - get_typ tenv t - | Closure _ | Constant (Cfun _) -> - (* We don't have a way to represent function types *) - None - | Constant (Cint _) -> - (* TODO: handle signedness *) - Some (Typ.mk (Typ.Tint Typ.IInt)) - | Constant (Cfloat _) -> - Some (Typ.mk (Typ.Tfloat Typ.FFloat)) - | Constant (Cclass _) -> - Some StdTyp.Java.pointer_to_java_lang_class - | Constant (Cstr _) -> - (* TODO: this will need to behave differently depending on whether we're in C++ or Java *) - None - | Cast (typ, _) -> - Some typ - | Sizeof _ -> - (* sizeof returns a size_t, which is an unsigned int *) - Some (Typ.mk (Typ.Tint Typ.IUInt)) - - let rec array_index_of_exp ~include_array_indexes ~f_resolve_id ~add_deref exp typ = if include_array_indexes then Some (of_sil ~include_array_indexes ~f_resolve_id ~add_deref exp typ) @@ -589,34 +552,6 @@ let rec is_int_zero = function false -let rec eval_arithmetic_binop op e1 e2 = - match (eval e1, eval e2) with - | Some (Const.Cint i1), Some (Const.Cint i2) -> - Some (Const.Cint (op i1 i2)) - | _ -> - None - - -and eval = function - | Constant c -> - Some c - | Cast (_, e) -> - eval e - | BinaryOperator (Binop.DivI, e1, e2) -> ( - try eval_arithmetic_binop IntLit.div e1 e2 with Division_by_zero -> None ) - | BinaryOperator (Binop.MinusA _, e1, e2) -> - eval_arithmetic_binop IntLit.sub e1 e2 - | BinaryOperator (Binop.Mod, e1, e2) -> - eval_arithmetic_binop IntLit.rem e1 e2 - | BinaryOperator (Binop.Mult _, e1, e2) -> - eval_arithmetic_binop IntLit.mul e1 e2 - | BinaryOperator (Binop.PlusA _, e1, e2) -> - eval_arithmetic_binop IntLit.add e1 e2 - | _ -> - (* TODO: handle bitshifting cases, port eval_binop from RacerD.ml *) - None - - let rec eval_boolean_binop op var e1 e2 = Option.both (eval_boolean_exp var e1) (eval_boolean_exp var e2) |> Option.map ~f:(fun (b1, b2) -> op b1 b2) diff --git a/infer/src/absint/HilExp.mli b/infer/src/absint/HilExp.mli index 156431e96f1..27ec031f064 100644 --- a/infer/src/absint/HilExp.mli +++ b/infer/src/absint/HilExp.mli @@ -85,9 +85,6 @@ end val pp : F.formatter -> t -> unit -val get_typ : Tenv.t -> t -> Typ.t option -(** Get the type of the expression. Warning: not fully implemented *) - val of_sil : include_array_indexes:bool -> f_resolve_id:(Var.t -> AccessExpression.t option) @@ -105,15 +102,13 @@ val is_null_literal : t -> bool val is_int_zero : t -> bool -val eval : t -> Const.t option +(* val eval : t -> Const.t option *) val eval_boolean_exp : AccessExpression.t -> t -> bool option (** [eval_boolean_exp var exp] returns [Some bool_value] if the given boolean expression [exp] evaluates to [bool_value] when [var] is set to true. Return None if it has free variables that stop us from evaluating it, or is not a boolean expression. *) -val ignore_cast : t -> t - val access_expr_of_exp : include_array_indexes:bool -> f_resolve_id:(Var.t -> AccessExpression.t option) diff --git a/infer/src/absint/Passthrough.ml b/infer/src/absint/Passthrough.ml index 32811b2f531..404fb8564f3 100644 --- a/infer/src/absint/Passthrough.ml +++ b/infer/src/absint/Passthrough.ml @@ -11,8 +11,6 @@ open! IStd etc. depending on what we need *) type t = {site: CallSite.t} [@@deriving compare] -let make site = {site} - let site t = t.site let pp fmt s = CallSite.pp fmt s.site diff --git a/infer/src/absint/Passthrough.mli b/infer/src/absint/Passthrough.mli index 1465a5d73f5..198c2ba6266 100644 --- a/infer/src/absint/Passthrough.mli +++ b/infer/src/absint/Passthrough.mli @@ -9,8 +9,6 @@ open! IStd type t [@@deriving compare] -val make : CallSite.t -> t - val site : t -> CallSite.t module Set : PrettyPrintable.PPSet with type elt = t diff --git a/infer/src/absint/Sink.ml b/infer/src/absint/Sink.ml index 057e0dbd147..ed6e0e3c70a 100644 --- a/infer/src/absint/Sink.ml +++ b/infer/src/absint/Sink.ml @@ -6,7 +6,6 @@ *) open! IStd -module F = Format module type Kind = sig include TaintTraceElem.Kind @@ -23,34 +22,3 @@ module type S = sig val with_indexes : t -> IntSet.t -> t end - -module Make (Kind : Kind) = struct - module Kind = Kind - - type t = {kind: Kind.t; site: CallSite.t; indexes: IntSet.t} [@@deriving compare, equal] - - let kind t = t.kind - - let call_site t = t.site - - let indexes t = t.indexes - - let make ?(indexes = IntSet.empty) kind site = {kind; site; indexes} - - let get site actuals call_flags tenv = - Kind.get (CallSite.pname site) actuals call_flags tenv - |> List.rev_map ~f:(fun (kind, indexes) -> {kind; site; indexes}) - - - let with_callsite t callee_site = {t with site= callee_site} - - let with_indexes t indexes = {t with indexes} - - let pp fmt s = F.fprintf fmt "%a(%a)" Kind.pp s.kind CallSite.pp s.site - - module Set = PrettyPrintable.MakePPSet (struct - type nonrec t = t [@@deriving compare] - - let pp = pp - end) -end diff --git a/infer/src/absint/Sink.mli b/infer/src/absint/Sink.mli index bfea6792be9..fbea4d8d514 100644 --- a/infer/src/absint/Sink.mli +++ b/infer/src/absint/Sink.mli @@ -25,5 +25,3 @@ module type S = sig val with_indexes : t -> IntSet.t -> t end - -module Make (Kind : Kind) : S with module Kind = Kind diff --git a/infer/src/absint/Source.ml b/infer/src/absint/Source.ml index d1341a8b936..13759bd41d5 100644 --- a/infer/src/absint/Source.ml +++ b/infer/src/absint/Source.ml @@ -6,12 +6,6 @@ *) open! IStd -module F = Format - -let all_formals_untainted pdesc = - let make_untainted (name, typ, _) = (name, typ, None) in - List.map ~f:make_untainted (Procdesc.get_formals pdesc) - module type Kind = sig include TaintTraceElem.Kind @@ -32,45 +26,6 @@ module type S = sig val get_tainted_formals : Procdesc.t -> Tenv.t -> (Mangled.t * Typ.t * t option) list end -module Make (Kind : Kind) = struct - module Kind = Kind - - type t = {kind: Kind.t; site: CallSite.t} [@@deriving compare, equal] - - type spec = {source: t; index: int option} - - let call_site t = t.site - - let kind t = t.kind - - let make ?indexes:_ kind site = {site; kind} - - let get ~caller_pname site actuals tenv = - Kind.get ~caller_pname (CallSite.pname site) actuals tenv - |> List.rev_map ~f:(fun (kind, index) -> - let source = make kind site in - {source; index} ) - - - let get_tainted_formals pdesc tenv = - let site = CallSite.make (Procdesc.get_proc_name pdesc) (Procdesc.get_loc pdesc) in - List.map - ~f:(fun (name, typ, kind_opt) -> - (name, typ, Option.map kind_opt ~f:(fun kind -> make kind site)) ) - (Kind.get_tainted_formals pdesc tenv) - - - let pp fmt s = F.fprintf fmt "%a(%a)" Kind.pp s.kind CallSite.pp s.site - - let with_callsite t callee_site = {t with site= callee_site} - - module Set = PrettyPrintable.MakePPSet (struct - type nonrec t = t [@@deriving compare] - - let pp = pp - end) -end - module Dummy = struct type t = unit [@@deriving compare, equal] diff --git a/infer/src/absint/Source.mli b/infer/src/absint/Source.mli index da4a6b783d2..abb5f3568e4 100644 --- a/infer/src/absint/Source.mli +++ b/infer/src/absint/Source.mli @@ -7,9 +7,6 @@ open! IStd -val all_formals_untainted : Procdesc.t -> (Mangled.t * Typ.t * 'a option) list -(** specify that all the formals of the procdesc are not tainted *) - module type Kind = sig include TaintTraceElem.Kind @@ -38,6 +35,4 @@ module type S = sig source, or None if the formal is not a taint source *) end -module Make (Kind : Kind) : S with module Kind = Kind - module Dummy : S with type t = unit diff --git a/infer/src/absint/TaintTrace.ml b/infer/src/absint/TaintTrace.ml index afe934ddd39..dd17dd5dfc6 100644 --- a/infer/src/absint/TaintTrace.ml +++ b/infer/src/absint/TaintTrace.ml @@ -517,14 +517,7 @@ module Make (Spec : Spec) = struct (Sinks.elements callee_trace.sinks) |> Sinks.of_list |> Sinks.union caller_trace.sinks in - let passthroughs = - if Config.quandary_show_passthroughs then - if phys_equal sources caller_trace.sources && phys_equal sinks caller_trace.sinks then - (* this callee didn't add any new sources or any news sinks; it's just a passthrough *) - Passthroughs.add (Passthrough.make callee_site) caller_trace.passthroughs - else caller_trace.passthroughs - else Passthroughs.empty - in + let passthroughs = caller_trace.passthroughs in {sources; sinks; passthroughs} diff --git a/infer/src/absint/annotations.ml b/infer/src/absint/annotations.ml index 52d0d816b9d..1eaeb954217 100644 --- a/infer/src/absint/annotations.ml +++ b/infer/src/absint/annotations.ml @@ -85,8 +85,6 @@ let thread_confined = "ThreadConfined" let thread_safe = "ThreadSafe" -let thrift_service = "ThriftService" - let ui_thread = "UiThread" let visibleForTesting = "VisibleForTesting" @@ -197,8 +195,6 @@ let ia_is_synchronized_collection ia = ia_ends_with ia synchronized_collection let ia_is_thread_safe ia = ia_ends_with ia thread_safe -let ia_is_thrift_service ia = ia_ends_with ia thrift_service - let ia_is_nonblocking ia = ia_ends_with ia nonblocking let ia_is_initializer ia = ia_ends_with ia initializer_ diff --git a/infer/src/absint/annotations.mli b/infer/src/absint/annotations.mli index 2da83bc2d19..312278c87e0 100644 --- a/infer/src/absint/annotations.mli +++ b/infer/src/absint/annotations.mli @@ -84,8 +84,6 @@ val ia_is_thread_safe : Annot.Item.t -> bool val ia_is_thread_confined : Annot.Item.t -> bool -val ia_is_thrift_service : Annot.Item.t -> bool - val ia_is_volatile : Annot.Item.t -> bool val ia_is_worker_thread : Annot.Item.t -> bool diff --git a/infer/src/backend/CallbackOfChecker.mli b/infer/src/backend/CallbackOfChecker.mli index 6656920c0d5..9f39871a487 100644 --- a/infer/src/backend/CallbackOfChecker.mli +++ b/infer/src/backend/CallbackOfChecker.mli @@ -10,13 +10,6 @@ open! IStd (** Conversions from checkers taking "functional" {!Absint.InterproceduralAnalysis.t} et al. payloads to {!Callbacks.proc_callback_t} and friends. *) -val mk_interprocedural_field_t : - (Payloads.t, 'payload Lazy.t option) Field.t - -> Callbacks.proc_callback_args - -> ?tenv:Tenv.t - -> unit - -> 'payload InterproceduralAnalysis.t * Summary.Stats.t ref - val interprocedural : AnalysisRequest.t -> f_analyze_dep:('payloads_orig -> 'payloads option) diff --git a/infer/src/backend/Payloads.ml b/infer/src/backend/Payloads.ml index 0d9f4263819..51acceb885c 100644 --- a/infer/src/backend/Payloads.ml +++ b/infer/src/backend/Payloads.ml @@ -21,7 +21,6 @@ type t = ; litho_required_props: LithoDomain.summary Lazy.t option ; pulse: PulseSummary.t Lazy.t option ; purity: PurityDomain.summary Lazy.t option - ; quandary: QuandarySummary.t Lazy.t option ; racerd: RacerDDomain.summary Lazy.t option ; scope_leakage: ScopeLeakage.Summary.t Lazy.t option ; siof: SiofDomain.Summary.t Lazy.t option @@ -59,7 +58,6 @@ let all_fields = ~litho_required_props:(fun f -> mk f LithoRequiredProps LithoDomain.pp_summary) ~pulse:(fun f -> mk f Pulse PulseSummary.pp) ~purity:(fun f -> mk f Purity PurityDomain.pp_summary) - ~quandary:(fun f -> mk f Quandary QuandarySummary.pp) ~racerd:(fun f -> mk f RacerD RacerDDomain.pp_summary) ~lab_resource_leaks:(fun f -> mk f LabResourceLeaks ResourceLeakDomain.pp) ~scope_leakage:(fun f -> mk f ScopeLeakage ScopeLeakage.Summary.pp) @@ -93,7 +91,6 @@ let empty = ; litho_required_props= None ; pulse= None ; purity= None - ; quandary= None ; racerd= None ; scope_leakage= None ; siof= None @@ -189,11 +186,10 @@ module SQLite = struct ~buffer_overrun_analysis:data_of_sqlite_column ~buffer_overrun_checker:data_of_sqlite_column ~config_impact_analysis:data_of_sqlite_column ~cost:data_of_sqlite_column ~disjunctive_demo:data_of_sqlite_column ~litho_required_props:data_of_sqlite_column - ~pulse:data_of_sqlite_column ~purity:data_of_sqlite_column ~quandary:data_of_sqlite_column - ~racerd:data_of_sqlite_column ~lab_resource_leaks:data_of_sqlite_column - ~scope_leakage:data_of_sqlite_column ~siof:data_of_sqlite_column - ~lineage:data_of_sqlite_column ~lineage_shape:data_of_sqlite_column - ~starvation:data_of_sqlite_column + ~pulse:data_of_sqlite_column ~purity:data_of_sqlite_column ~racerd:data_of_sqlite_column + ~lab_resource_leaks:data_of_sqlite_column ~scope_leakage:data_of_sqlite_column + ~siof:data_of_sqlite_column ~lineage:data_of_sqlite_column + ~lineage_shape:data_of_sqlite_column ~starvation:data_of_sqlite_column let eager_load stmt ~first_column = (make_eager first_column |> fst) stmt @@ -244,7 +240,6 @@ module SQLite = struct ; litho_required_props= load table ~proc_uid LithoRequiredProps ; pulse= load table ~proc_uid Pulse ; purity= load table ~proc_uid Purity - ; quandary= load table ~proc_uid Quandary ; racerd= load table ~proc_uid RacerD ; scope_leakage= load table ~proc_uid ScopeLeakage ; siof= load table ~proc_uid SIOF diff --git a/infer/src/backend/Payloads.mli b/infer/src/backend/Payloads.mli index 010d4b102ee..ac8fc3cb280 100644 --- a/infer/src/backend/Payloads.mli +++ b/infer/src/backend/Payloads.mli @@ -30,7 +30,6 @@ include sig ; litho_required_props: LithoDomain.summary Lazy.t option ; pulse: PulseSummary.t Lazy.t option ; purity: PurityDomain.summary Lazy.t option - ; quandary: QuandarySummary.t Lazy.t option ; racerd: RacerDDomain.summary Lazy.t option ; scope_leakage: ScopeLeakage.Summary.t Lazy.t option ; siof: SiofDomain.Summary.t Lazy.t option diff --git a/infer/src/backend/dune b/infer/src/backend/dune index 3f27453a1ce..359ac3c75c8 100644 --- a/infer/src/backend/dune +++ b/infer/src/backend/dune @@ -37,8 +37,6 @@ -open Costlib -open - Quandary - -open Topllib -open Concurrency @@ -59,7 +57,6 @@ BO Checkers Costlib - Quandary Topllib Concurrency Labs diff --git a/infer/src/backend/registerCheckers.ml b/infer/src/backend/registerCheckers.ml index ffc826e0161..0ff2a745945 100644 --- a/infer/src/backend/registerCheckers.ml +++ b/infer/src/backend/registerCheckers.ml @@ -164,10 +164,6 @@ let all_checkers = ; (racerd_file, Clang) ; (racerd_file, Java) ; (racerd_file, CIL) ] ) } - ; { checker= Quandary - ; callbacks= - [ (interprocedural Payloads.Fields.quandary JavaTaintAnalysis.checker, Java) - ; (interprocedural Payloads.Fields.quandary ClangTaintAnalysis.checker, Clang) ] } ; { checker= DisjunctiveDemo ; callbacks= [(interprocedural Payloads.Fields.disjunctive_demo DisjunctiveDemo.checker, Clang)] } diff --git a/infer/src/backend/tests/dune b/infer/src/backend/tests/dune index 4fbacdc5fac..a3f2b1a7224 100644 --- a/infer/src/backend/tests/dune +++ b/infer/src/backend/tests/dune @@ -37,8 +37,6 @@ -open Costlib -open - Quandary - -open Topllib -open Concurrency @@ -63,7 +61,6 @@ BO Checkers Costlib - Quandary Topllib Concurrency Labs diff --git a/infer/src/base/Checker.ml b/infer/src/base/Checker.ml index 6e7cadc0fe3..203784e0701 100644 --- a/infer/src/base/Checker.ml +++ b/infer/src/base/Checker.ml @@ -31,7 +31,6 @@ type t = | Pulse | PurityAnalysis | PurityChecker - | Quandary | RacerD | ResourceLeakLabExercise | SILValidation @@ -307,23 +306,6 @@ let config_unsafe checker = ; cli_flags= Some {deprecated= []; show_in_help= true} ; enabled_by_default= false ; activates= [PurityAnalysis] } - | Quandary -> - { id= "quandary" - ; kind= - UserFacingDeprecated - { title= "Quandary" - ; deprecation_message= - "Taint analysis is now supported by the Pulse checker and Quandary will be removed \ - in the next release." - ; markdown_body= [%blob "./documentation/checkers/Quandary.md"] } - ; support= mk_support_func ~clang:Support ~java:Support () - ; short_documentation= - "The Quandary taint analysis detects flows of values between sources and sinks, except \ - if the value went through a \"sanitizer\". In addition to some defaults, users can \ - specify their own sources, sinks, and sanitizers functions." - ; cli_flags= Some {deprecated= []; show_in_help= true} - ; enabled_by_default= false - ; activates= [] } | RacerD -> { id= "racerd" ; kind= diff --git a/infer/src/base/Checker.mli b/infer/src/base/Checker.mli index fee9f812c58..52d3076ce7c 100644 --- a/infer/src/base/Checker.mli +++ b/infer/src/base/Checker.mli @@ -30,7 +30,6 @@ type t = | Pulse | PurityAnalysis | PurityChecker - | Quandary | RacerD | ResourceLeakLabExercise | SILValidation diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 946064a42f4..be5ed62a211 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -177,8 +177,6 @@ let manual_lineage = "LINEAGE OPTIONS" let manual_pulse = "PULSE CHECKER OPTIONS" -let manual_quandary = "QUANDARY CHECKER OPTIONS" - let manual_racerd = "RACERD CHECKER OPTIONS" let manual_scheduler = "ANALYSIS SCHEDULER OPTIONS" @@ -2991,36 +2989,6 @@ and qualified_cpp_name_block_list = "Skip analyzing the procedures under the qualified cpp type name." -and quandary_endpoints = - CLOpt.mk_json ~long:"quandary-endpoints" - ~in_help:InferCommand.[(Analyze, manual_quandary)] - "Specify endpoint classes for Quandary" - - -and quandary_sanitizers = - CLOpt.mk_json ~long:"quandary-sanitizers" - ~in_help:InferCommand.[(Analyze, manual_quandary)] - "Specify custom sanitizers for Quandary" - - -and quandary_show_passthroughs = - CLOpt.mk_bool ~deprecated:["-passthroughs"] ~long:"quandary-show-passthroughs" ~default:false - "In error traces, show intermediate steps that propagate data. When false, error traces are \ - shorter and show only direct flow via souces/sinks" - - -and quandary_sinks = - CLOpt.mk_json ~long:"quandary-sinks" - ~in_help:InferCommand.[(Analyze, manual_quandary)] - "Specify custom sinks for Quandary" - - -and quandary_sources = - CLOpt.mk_json ~long:"quandary-sources" - ~in_help:InferCommand.[(Analyze, manual_quandary)] - "Specify custom sources for Quandary" - - and quiet = CLOpt.mk_bool ~long:"quiet" ~short:'q' ~default:false ~in_help:InferCommand.[(Analyze, manual_generic); (Report, manual_generic)] @@ -4691,16 +4659,6 @@ and python_builtin_models = !python_builtin_models and qualified_cpp_name_block_list = RevList.to_list !qualified_cpp_name_block_list -and quandary_endpoints = !quandary_endpoints - -and quandary_sanitizers = !quandary_sanitizers - -and quandary_show_passthroughs = !quandary_show_passthroughs - -and quandary_sinks = !quandary_sinks - -and quandary_sources = !quandary_sources - and quiet = !quiet and racerd_always_report_java = !racerd_always_report_java diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index aeb9b91ca47..197460ff977 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -728,16 +728,6 @@ val python_builtin_models : string val qualified_cpp_name_block_list : string list -val quandary_endpoints : Yojson.Safe.t - -val quandary_sanitizers : Yojson.Safe.t - -val quandary_show_passthroughs : bool - -val quandary_sinks : Yojson.Safe.t - -val quandary_sources : Yojson.Safe.t - val quiet : bool val racerd_always_report_java : bool diff --git a/infer/src/base/IssueType.ml b/infer/src/base/IssueType.ml index b6bad2d72ce..3df904f73f1 100644 --- a/infer/src/base/IssueType.ml +++ b/infer/src/base/IssueType.ml @@ -533,18 +533,6 @@ let cxx_ref_captured_in_block = ~user_documentation:[%blob "./documentation/issues/CXX_REF_CAPTURED_IN_BLOCK.md"] -let create_intent_from_uri = - register ~category:NoCategory ~id:"CREATE_INTENT_FROM_URI" Error Quandary - ~user_documentation: - "Create an intent/start a component using a (possibly user-controlled) URI. may or may not \ - be an issue depending on where the URI comes from." - - -let cross_site_scripting = - register ~category:NoCategory ~id:"CROSS_SITE_SCRIPTING" Error Quandary - ~user_documentation:"Untrusted data flows into HTML; XSS risk." - - let dangling_pointer_dereference = register ~category:NoCategory ~enabled:false ~id:"DANGLING_POINTER_DEREFERENCE" Error Biabduction (* TODO *) @@ -570,18 +558,13 @@ let divide_by_zero = ~user_documentation:"" -let do_not_report = register_hidden ~id:"DO_NOT_REPORT" Error Quandary +let do_not_report = register_hidden ~id:"DO_NOT_REPORT" Error SIOF let empty_vector_access = register ~category:NoCategory ~id:"EMPTY_VECTOR_ACCESS" Error Biabduction ~user_documentation:[%blob "./documentation/issues/EMPTY_VECTOR_ACCESS.md"] -let exposed_insecure_intent_handling = - register ~category:NoCategory ~id:"EXPOSED_INSECURE_INTENT_HANDLING" Error Quandary - ~user_documentation:"Undocumented." - - let expensive_cost_call ~kind = register_cost ~enabled:false "EXPENSIVE_%s" ~kind let failure_exe = register_hidden ~is_silent:true ~id:"Failure_exe" Info Biabduction @@ -649,11 +632,6 @@ let inherently_dangerous_function = register_hidden ~id:"INHERENTLY_DANGEROUS_FUNCTION" Warning Biabduction -let insecure_intent_handling = - register ~category:NoCategory ~id:"INSECURE_INTENT_HANDLING" Error Quandary - ~user_documentation:"Undocumented." - - let integer_overflow_l1 = register ~category:NoCategory ~id:"INTEGER_OVERFLOW_L1" Error BufferOverrunChecker ~user_documentation:[%blob "./documentation/issues/INTEGER_OVERFLOW.md"] @@ -696,11 +674,6 @@ let ipc_on_ui_thread = ~user_documentation:"A blocking `Binder` IPC call occurs on the UI thread." -let javascript_injection = - register ~category:NoCategory ~id:"JAVASCRIPT_INJECTION" Error Quandary - ~user_documentation:"Untrusted data flows into JavaScript." - - let lab_resource_leak = register ~category:NoCategory ~id:"LAB_RESOURCE_LEAK" Error ResourceLeakLabExercise ~user_documentation:"Toy issue." @@ -724,11 +697,6 @@ let lockless_violation = ~user_documentation:[%blob "./documentation/issues/LOCKLESS_VIOLATION.md"] -let logging_private_data = - register ~category:NoCategory ~id:"LOGGING_PRIVATE_DATA" Error Quandary - ~user_documentation:"Undocumented." - - let expensive_loop_invariant_call = register ~category:NoCategory ~id:"EXPENSIVE_LOOP_INVARIANT_CALL" Error LoopHoisting ~user_documentation:[%blob "./documentation/issues/EXPENSIVE_LOOP_INVARIANT_CALL.md"] @@ -901,11 +869,6 @@ let pure_function = ~user_documentation:[%blob "./documentation/issues/PURE_FUNCTION.md"] -let quandary_taint_error = - register ~category:NoCategory ~hum:"Taint Error" ~id:"QUANDARY_TAINT_ERROR" Error Quandary - ~user_documentation:"Generic taint error when nothing else fits." - - let readonly_shared_ptr_param = register ~category:PerfRegression ~id:"PULSE_READONLY_SHARED_PTR_PARAM" Error Pulse ~hum:"Read-only Shared Parameter" @@ -962,26 +925,6 @@ let scope_leakage = let skip_function = register_hidden ~enabled:false ~id:"SKIP_FUNCTION" Info Biabduction -let shell_injection = - register ~category:NoCategory ~id:"SHELL_INJECTION" Error Quandary - ~user_documentation:"Environment variable or file data flowing to shell." - - -let shell_injection_risk = - register ~category:NoCategory ~id:"SHELL_INJECTION_RISK" Error Quandary - ~user_documentation:"Code injection if the caller of the endpoint doesn't sanitize on its end." - - -let sql_injection = - register ~category:NoCategory ~id:"SQL_INJECTION" Error Quandary - ~user_documentation:"Untrusted and unescaped data flows to SQL." - - -let sql_injection_risk = - register ~category:NoCategory ~id:"SQL_INJECTION_RISK" Error Quandary - ~user_documentation:"Untrusted and unescaped data flows to SQL." - - let stack_variable_address_escape = register ~category:MemoryError ~id:"STACK_VARIABLE_ADDRESS_ESCAPE" Error Pulse ~user_documentation:[%blob "./documentation/issues/STACK_VARIABLE_ADDRESS_ESCAPE.md"] @@ -1108,66 +1051,6 @@ let use_after_lifetime = ~user_documentation:[%blob "./documentation/issues/USE_AFTER_LIFETIME.md"] -let user_controlled_sql_risk = - register ~category:NoCategory ~id:"USER_CONTROLLED_SQL_RISK" Error Quandary - ~user_documentation:"Untrusted data flows to SQL (no injection risk)." - - -let untrusted_buffer_access = - register ~category:NoCategory ~enabled:false ~id:"UNTRUSTED_BUFFER_ACCESS" Error Quandary - ~user_documentation:"Untrusted data of any kind flowing to buffer." - - -let untrusted_deserialization = - register ~category:NoCategory ~id:"UNTRUSTED_DESERIALIZATION" Error Quandary - ~user_documentation:"User-controlled deserialization." - - -let untrusted_deserialization_risk = - register ~category:NoCategory ~id:"UNTRUSTED_DESERIALIZATION_RISK" Error Quandary - ~user_documentation:"User-controlled deserialization" - - -let untrusted_environment_change_risk = - register ~category:NoCategory ~id:"UNTRUSTED_ENVIRONMENT_CHANGE_RISK" Error Quandary - ~user_documentation:"User-controlled environment mutation." - - -let untrusted_file = - register ~category:NoCategory ~id:"UNTRUSTED_FILE" Error Quandary - ~user_documentation: - "User-controlled file creation; may be vulnerable to path traversal and more." - - -let untrusted_file_risk = - register ~category:NoCategory ~id:"UNTRUSTED_FILE_RISK" Error Quandary - ~user_documentation: - "User-controlled file creation; may be vulnerable to path traversal and more." - - -let untrusted_heap_allocation = - register ~category:NoCategory ~enabled:false ~id:"UNTRUSTED_HEAP_ALLOCATION" Error Quandary - ~user_documentation: - "Untrusted data of any kind flowing to heap allocation. this can cause crashes or DOS." - - -let untrusted_intent_creation = - register ~category:NoCategory ~id:"UNTRUSTED_INTENT_CREATION" Error Quandary - ~user_documentation:"Creating an Intent from user-controlled data." - - -let untrusted_url_risk = - register ~category:NoCategory ~id:"UNTRUSTED_URL_RISK" Error Quandary - ~user_documentation:"Untrusted flag, environment variable, or file data flowing to URL." - - -let untrusted_variable_length_array = - register ~category:NoCategory ~id:"UNTRUSTED_VARIABLE_LENGTH_ARRAY" Error Quandary - ~user_documentation: - "Untrusted data of any kind flowing to stack buffer allocation. Trying to allocate a stack \ - buffer that's too large will cause a stack overflow." - - let vector_invalidation = register_with_latent ~category:MemoryError ~id:"VECTOR_INVALIDATION" Error Pulse ~user_documentation:[%blob "./documentation/issues/VECTOR_INVALIDATION.md"] diff --git a/infer/src/base/IssueType.mli b/infer/src/base/IssueType.mli index 23f8d54a70d..6c7f5143a09 100644 --- a/infer/src/base/IssueType.mli +++ b/infer/src/base/IssueType.mli @@ -171,10 +171,6 @@ val constant_address_dereference : latent:bool -> t val cxx_ref_captured_in_block : t -val create_intent_from_uri : t - -val cross_site_scripting : t - val dangling_pointer_dereference : t val dangling_pointer_dereference_maybe : t @@ -194,8 +190,6 @@ val do_not_report : t val empty_vector_access : t -val exposed_insecure_intent_handling : t - val expensive_cost_call : kind:CostKind.t -> t val failure_exe : t @@ -220,8 +214,6 @@ val infinite_cost_call : kind:CostKind.t -> t val inherently_dangerous_function : t -val insecure_intent_handling : t - val integer_overflow_l1 : t val integer_overflow_l2 : t @@ -240,8 +232,6 @@ val invariant_call : t val ipc_on_ui_thread : t -val javascript_injection : t - val lab_resource_leak : t val leak_after_array_abstraction : t @@ -254,8 +244,6 @@ val lockless_violation : t val lock_consistency_violation : t -val logging_private_data : t - val expensive_loop_invariant_call : t val memory_leak : t @@ -326,8 +314,6 @@ val pulse_uninitialized_const : t val pure_function : t -val quandary_taint_error : t - val readonly_shared_ptr_param : t val regex_op_on_ui_thread : t @@ -344,14 +330,6 @@ val sensitive_data_flow : t val skip_function : t -val shell_injection : t - -val shell_injection_risk : t - -val sql_injection : t - -val sql_injection_risk : t - val stack_variable_address_escape : t val starvation : t @@ -400,28 +378,6 @@ val use_after_free : latent:bool -> t val use_after_lifetime : latent:bool -> t -val untrusted_buffer_access : t - -val untrusted_deserialization : t - -val untrusted_deserialization_risk : t - -val untrusted_file : t - -val untrusted_file_risk : t - -val untrusted_heap_allocation : t - -val untrusted_intent_creation : t - -val untrusted_url_risk : t - -val untrusted_environment_change_risk : t - -val untrusted_variable_length_array : t - -val user_controlled_sql_risk : t - val vector_invalidation : latent:bool -> t val pulse_reference_stability : t diff --git a/infer/src/base/PayloadId.ml b/infer/src/base/PayloadId.ml index 76a0d4255db..746616c117f 100644 --- a/infer/src/base/PayloadId.ml +++ b/infer/src/base/PayloadId.ml @@ -19,7 +19,6 @@ type t = | LithoRequiredProps | Pulse | Purity - | Quandary | RacerD | ScopeLeakage | SIOF @@ -54,8 +53,6 @@ let to_checker payload_id : Checker.t = Pulse | Purity -> PurityAnalysis - | Quandary -> - Quandary | RacerD -> RacerD | ScopeLeakage -> diff --git a/infer/src/base/PayloadId.mli b/infer/src/base/PayloadId.mli index afffb9a271e..eeda45e0ab5 100644 --- a/infer/src/base/PayloadId.mli +++ b/infer/src/base/PayloadId.mli @@ -20,7 +20,6 @@ type t = | LithoRequiredProps | Pulse | Purity - | Quandary | RacerD | ScopeLeakage | SIOF diff --git a/infer/src/biabduction/BuiltinDefn.ml b/infer/src/biabduction/BuiltinDefn.ml index 3179354774d..62993f5f9b0 100644 --- a/infer/src/biabduction/BuiltinDefn.ml +++ b/infer/src/biabduction/BuiltinDefn.ml @@ -833,9 +833,6 @@ let execute___objc_dictionary_literal builtin_args = execute_objc_NSDictionary_alloc_no_fail res' pname builtin_args -(* only used in Quandary, so ok to skip *) -let __array_access = Builtin.register BuiltinDecl.__array_access execute_skip - let __assert_fail = Builtin.register BuiltinDecl.__assert_fail execute___assert_fail let __builtin_add_overflow = Builtin.register BuiltinDecl.__builtin_add_overflow execute_skip @@ -877,9 +874,6 @@ let __get_array_length = Builtin.register BuiltinDecl.__get_array_length execute let __get_type_of = Builtin.register BuiltinDecl.__get_type_of execute___get_type_of -(* only used in Quandary, so ok to skip *) -let __global_access = Builtin.register BuiltinDecl.__global_access execute_skip - (* infer assume, diverging on inconsistencies *) let __infer_assume = Builtin.register BuiltinDecl.__infer_assume execute___infer_assume diff --git a/infer/src/deadcode/Makefile b/infer/src/deadcode/Makefile index 848f2de2d36..12b9d939b11 100644 --- a/infer/src/deadcode/Makefile +++ b/infer/src/deadcode/Makefile @@ -50,8 +50,8 @@ endif # Note that we run find under _build directory. Since we copy some # sources from subfolders to src/ folder to avoid duplicates we use # $(DEPTH_ONE) and iteration over main and library folders. -LIBRARY_FOLDERS = . ./IR ./textual ./python ./absint ./atd ./backend ./base ./biabduction ./bufferoverrun ./c_stubs ./checkers ./clang ./clang/unit ./concurrency ./cost ./datalog ./erlang ./integration ./istd ./java ./labs ./dotnet ./pulse ./quandary ./scripts ./test_determinator ./topl ./unit -INCLUDE_FOLDERS = -I IR -I textual -I textual/unit -I python -I python/unit -I absint -I atd -I backend -I base -I biabduction -I bufferoverrun -I c_stubs -I checkers -I clang -I clang/unit -I concurrency -I cost -I datalog -I erlang -I integration -I istd -I java -I labs -I pulse -I quandary -I scripts -I test_determinator -I topl -I unit +LIBRARY_FOLDERS = . ./IR ./textual ./python ./absint ./atd ./backend ./base ./biabduction ./bufferoverrun ./c_stubs ./checkers ./clang ./clang/unit ./concurrency ./cost ./datalog ./erlang ./integration ./istd ./java ./labs ./dotnet ./pulse ./scripts ./test_determinator ./topl ./unit +INCLUDE_FOLDERS = -I IR -I textual -I textual/unit -I python -I python/unit -I absint -I atd -I backend -I base -I biabduction -I bufferoverrun -I c_stubs -I checkers -I clang -I clang/unit -I concurrency -I cost -I datalog -I erlang -I integration -I istd -I java -I labs -I pulse -I scripts -I test_determinator -I topl -I unit ml_src_files = $(shell \ cd $(INFER_BUILD_DIR); \ diff --git a/infer/src/dune.in b/infer/src/dune.in index ce486f88ea2..da8befa896d 100644 --- a/infer/src/dune.in +++ b/infer/src/dune.in @@ -120,7 +120,7 @@ let infertop_stanza = (modes byte_complete) (modules Infertop) (flags (:standard -open Core -open IStdlib -open IStd -open Textuallib %s)) - (libraries %s utop Absint ATDGenerated Backend IBase Biabduction BO Checkers Concurrency Costlib CStubs IR Textuallib IStdlib Labs Pulselib PythonFrontend Quandary Integration TestDeterminators Topllib UnitTests) + (libraries %s utop Absint ATDGenerated Backend IBase Biabduction BO Checkers Concurrency Costlib CStubs IR Textuallib IStdlib Labs Pulselib PythonFrontend Integration TestDeterminators Topllib UnitTests) (link_flags (-linkall -warn-error -31)) (preprocess (pps ppx_compare)) (promote (until-clean) (into ../bin)) diff --git a/infer/src/inferunit.ml b/infer/src/inferunit.ml index b722ba213c3..2c3792ba7d8 100644 --- a/infer/src/inferunit.ml +++ b/infer/src/inferunit.ml @@ -43,8 +43,6 @@ let () = ; RestartSchedulerTests.tests ; SchedulerTests.tests ; SeverityTests.tests - ; TaintTests.tests - ; TraceTests.tests ; WeakTopologicalOrderTests.tests ] @ ClangTests.tests ) in diff --git a/infer/src/quandary/ClangTaintAnalysis.ml b/infer/src/quandary/ClangTaintAnalysis.ml deleted file mode 100644 index 3475564e5fd..00000000000 --- a/infer/src/quandary/ClangTaintAnalysis.ml +++ /dev/null @@ -1,104 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd - -include TaintAnalysis.Make (struct - module Trace = ClangTrace - module AccessTree = AccessTree.Make (Trace) (AccessTree.DefaultConfig) - - let to_summary_access_tree tree = QuandarySummary.AccessTree.Clang tree - - let of_summary_access_tree = function - | QuandarySummary.AccessTree.Clang tree -> - tree - | _ -> - assert false - - - let handle_unknown_call pname ret_typ actuals _ = - let handle_generic_unknown ret_typ actuals = - match ((ret_typ.Typ.desc : Typ.desc), List.rev_map actuals ~f:HilExp.ignore_cast) with - (* everything but Tvoid*) - | (Tint _ | Tfloat _ | Tfun | Tptr _ | Tstruct _ | TVar _ | Tarray _), _ -> - (* propagate taint from actuals to return value *) - [TaintSpec.Propagate_to_return] - | Tvoid, [] -> - [] - | Tvoid, _ when Procname.is_constructor pname -> - (* "this" is always the first arg of a constructor; propagate taint there *) - [TaintSpec.Propagate_to_receiver] - | Tvoid, HilExp.AccessExpression access_expr :: _ -> ( - match HilExp.AccessExpression.to_access_path access_expr with - | (Var.ProgramVar pvar, {desc= Typ.Tptr (_, Typ.Pk_pointer)}), [] - when Pvar.is_frontend_tmp pvar -> - (* no return value, but the frontend has introduced a dummy return variable and will - assign the return value to this variable. So propagate taint to the dummy return - variable *) - let actual_index = List.length actuals - 1 in - [TaintSpec.Propagate_to_actual actual_index] - | _ -> - [TaintSpec.Propagate_to_receiver] ) - | Tvoid, _ -> - (* no return value; propagate taint from actuals to receiver *) - [TaintSpec.Propagate_to_receiver] - in - (* if we have a specific model for a procedure, use that. otherwise, use the generic - heuristics for dealing with unknown code *) - match Procname.get_method pname with - | "operator+=" - | "operator-=" - | "operator*=" - | "operator/=" - | "operator%=" - | "operator<<=" - | "operator>>=" - | "operator&=" - | "operator^=" - | "operator|=" -> - [TaintSpec.Propagate_to_receiver; TaintSpec.Propagate_to_return] - | "memcpy" | "memmove" | "strcpy" | "strncpy" -> - [TaintSpec.Propagate_to_receiver; TaintSpec.Propagate_to_return] - | "sprintf" -> - [TaintSpec.Propagate_to_receiver] - | "strlen" -> - (* don't propagate taint for strlen *) - [] - | _ -> - handle_generic_unknown ret_typ actuals - - - (* treat folly functions as unknown library code. we often specify folly functions as sinks, - and we don't want to double-report if these functions eventually call other sinks (e.g., - when folly::Subprocess calls exec), in addition some folly functions are heavily optimized in - a way that obscures what they're actually doing (e.g., they use assembly code). it's better - to write models for these functions or treat them as unknown *) - let models_matcher = QualifiedCppName.Match.of_fuzzy_qual_names ["folly"] - - let get_model pname ret_typ actuals tenv summary = - (* hack for default C++ constructors, which get translated as an empty body (and will thus - have an empty summary). We don't want that because we want to be able to propagate taint - from comstructor parameters to the constructed object. so we treat the empty constructor - as a skip function instead *) - let is_default_constructor pname = - Procname.is_c_method pname && Procname.is_constructor pname - && AccessTree.BaseMap.is_empty summary - in - match pname with - | Procname.ObjC_Cpp _ - when is_default_constructor pname - || QualifiedCppName.Match.match_qualifiers models_matcher (Procname.get_qualifiers pname) - -> - Some (handle_unknown_call pname ret_typ actuals tenv) - | _ -> - None - - - let is_taintable_type _ = true - - let name = "clang" -end) diff --git a/infer/src/quandary/ClangTaintAnalysis.mli b/infer/src/quandary/ClangTaintAnalysis.mli deleted file mode 100644 index ca77632a235..00000000000 --- a/infer/src/quandary/ClangTaintAnalysis.mli +++ /dev/null @@ -1,10 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd - -val checker : QuandarySummary.t InterproceduralAnalysis.t -> QuandarySummary.t option diff --git a/infer/src/quandary/ClangTrace.ml b/infer/src/quandary/ClangTrace.ml deleted file mode 100644 index a7d6caa679a..00000000000 --- a/infer/src/quandary/ClangTrace.ml +++ /dev/null @@ -1,527 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd -module F = Format -module L = Logging - -let parse_clang_procedure procedure kinds index = - try Some (QualifiedCppName.Match.of_fuzzy_qual_names [procedure], kinds, index) - with QualifiedCppName.ParseError _ -> - (* Java and Clang sources/sinks live in the same inferconfig entry. If we try to parse a Java - procedure that happens to be an invalid Clang qualified name (e.g., MyClass.), - parsing will crash. In the future, we can avoid this by requiring JSON source/sink - specifications to indicate the language *) - None - - -module SourceKind = struct - type t = - | CommandLineFlag of (Var.t * Typ.desc) (** source that was read from a command line flag *) - | Endpoint of (Mangled.t * Typ.desc) (** source originating from formal of an endpoint *) - | EnvironmentVariable (** source that was read from an environment variable *) - | ReadFile (** source that was read from a file *) - | Other (** for testing or uncategorized sources *) - | UserControlledEndpoint of (Mangled.t * Typ.desc) - (** source originating from formal of an endpoint that is known to hold user-controlled data *) - [@@deriving compare, equal] - - let matches ~caller ~callee = Int.equal 0 (compare caller callee) - - let of_string = function - | "CommandLineFlag" -> - L.die UserError "User-specified CommandLineFlag sources are not supported" - | "Endpoint" -> - Endpoint (Mangled.from_string "NONE", Typ.Tvoid) - | "EnvironmentVariable" -> - EnvironmentVariable - | "ReadFile" -> - ReadFile - | "UserControlledEndpoint" -> - Endpoint (Mangled.from_string "NONE", Typ.Tvoid) - | _ -> - Other - - - let external_sources = - List.filter_map - ~f:(fun {QuandaryConfig.Source.procedure; kinds; index} -> - parse_clang_procedure procedure kinds index ) - (QuandaryConfig.Source.of_json Config.quandary_sources) - - - (* return a list of source kinds if [procedure_name] is in the list of externally specified sources *) - let get_external_source qualified_pname = - let return = None in - List.concat_map external_sources ~f:(fun (qualifiers, kinds, index) -> - if QualifiedCppName.Match.match_qualifiers qualifiers qualified_pname then - let source_index = try Some (int_of_string index) with Failure _ -> return in - List.rev_map kinds ~f:(fun kind -> (of_string kind, source_index)) - else [] ) - - - let get ~caller_pname:_ pname actuals tenv = - let return = None in - match pname with - | Procname.ObjC_Cpp cpp_name -> ( - let qualified_pname = Procname.get_qualifiers pname in - match - ( QualifiedCppName.to_list - (Typ.Name.unqualified_name (Procname.ObjC_Cpp.get_class_type_name cpp_name)) - , Procname.get_method pname ) - with - | ( ["std"; ("basic_istream" | "basic_iostream")] - , ("getline" | "read" | "readsome" | "operator>>") ) -> - [(ReadFile, Some 1)] - | _ -> - get_external_source qualified_pname ) - | Procname.C _ when Procname.equal pname BuiltinDecl.__global_access -> ( - (* is this var a command line flag created by the popular C++ gflags library for creating - command-line flags (https://github.com/gflags/gflags)? *) - let is_gflag access_path = - let pvar_is_gflag pvar = - String.is_substring ~substring:"FLAGS_" (Pvar.get_simplified_name pvar) - in - match access_path with - | (Var.ProgramVar pvar, _), _ -> - Pvar.is_global pvar && pvar_is_gflag pvar - | _ -> - false - in - (* accessed global will be passed to us as the only parameter *) - match List.map actuals ~f:HilExp.ignore_cast with - | [HilExp.AccessExpression access_expr] -> - let access_path = HilExp.AccessExpression.to_access_path access_expr in - if is_gflag access_path then - let (global_pvar, _), _ = access_path in - let typ_desc = - match AccessPath.get_typ access_path tenv with - | Some {Typ.desc} -> - desc - | None -> - StdTyp.void_star.desc - in - [(CommandLineFlag (global_pvar, typ_desc), None)] - else [] - | _ -> - [] ) - | Procname.C _ -> ( - match Procname.to_string pname with - | "getenv" -> - [(EnvironmentVariable, return)] - | _ -> - get_external_source (Procname.get_qualifiers pname) ) - | Procname.Block _ -> - [] - | pname -> - L.(die InternalError) "Non-C++ procname %a in C++ analysis" Procname.pp pname - - - let get_tainted_formals pdesc tenv = - if ProcAttributes.equal_access (Procdesc.get_access pdesc) Private then - Source.all_formals_untainted pdesc - else - let overrides_service_method pname tenv = - PatternMatch.override_exists - (function - | Procname.ObjC_Cpp cpp_pname -> - let class_name = Procname.ObjC_Cpp.get_class_name cpp_pname in - let res = - String.is_suffix ~suffix:"SvIf" class_name - || String.is_suffix ~suffix:"SvAsyncIf" class_name - in - res - | _ -> - false ) - tenv pname - in - (* taint all formals except for [this] *) - let taint_all_but_this_and_return ~make_source = - List.map - ~f:(fun (name, typ, _) -> - let taint = - match Mangled.to_string name with - | "this" | "_return" -> - (* thrift methods implement returning values using dummy _return parameters that - the C++ code assigns to. these are sinks, not sources *) - None - | _ -> - Some (make_source name typ.Typ.desc) - in - (name, typ, taint) ) - (Procdesc.get_formals pdesc) - in - match Procdesc.get_proc_name pdesc with - | Procname.ObjC_Cpp cpp_pname as pname -> - let qualified_pname = - F.sprintf "%s::%s" - (Procname.ObjC_Cpp.get_class_name cpp_pname) - (Procname.get_method pname) - in - if QuandaryConfig.is_endpoint qualified_pname then - taint_all_but_this_and_return ~make_source:(fun name desc -> - UserControlledEndpoint (name, desc) ) - else if overrides_service_method pname tenv then - taint_all_but_this_and_return ~make_source:(fun name desc -> Endpoint (name, desc)) - else Source.all_formals_untainted pdesc - | _ -> - Source.all_formals_untainted pdesc - - - let pp fmt = function - | Endpoint (formal_name, _) -> - F.fprintf fmt "Endpoint(%s)" (Mangled.to_string formal_name) - | EnvironmentVariable -> - F.pp_print_string fmt "EnvironmentVariable" - | ReadFile -> - F.pp_print_string fmt "File" - | CommandLineFlag (var, _) -> - F.fprintf fmt "CommandLineFlag(%a)" Var.pp var - | Other -> - F.pp_print_string fmt "Other" - | UserControlledEndpoint (formal_name, _) -> - F.fprintf fmt "UserControlledEndpoint(%s)" (Mangled.to_string formal_name) -end - -module CppSource = Source.Make (SourceKind) - -module SinkKind = struct - type t = - | BufferAccess (** read/write an array *) - | CreateFile (** create/open a file *) - | EnvironmentChange (** change environment variable or gflag *) - | HeapAllocation (** heap memory allocation *) - | ShellExec (** shell exec function *) - | SQLInjection (** unescaped query to a SQL database (could be read or write) *) - | SQLRead (** escaped read to a SQL database *) - | SQLWrite (** escaped write to a SQL database *) - | StackAllocation (** stack memory allocation *) - | URL (** URL creation *) - | Other (** for testing or uncategorized sinks *) - [@@deriving compare, equal] - - let matches ~caller ~callee = Int.equal 0 (compare caller callee) - - let of_string = function - | "BufferAccess" -> - BufferAccess - | "CreateFile" -> - CreateFile - | "EnvironmentChange" -> - EnvironmentChange - | "HeapAllocation" -> - HeapAllocation - | "ShellExec" -> - ShellExec - | "SQLInjection" -> - SQLInjection - | "SQLRead" -> - SQLRead - | "SQLWrite" -> - SQLWrite - | "StackAllocation" -> - StackAllocation - | "URL" -> - URL - | _ -> - Other - - - let external_sinks = - List.filter_map - ~f:(fun {QuandaryConfig.Sink.procedure; kinds; index} -> - parse_clang_procedure procedure kinds index ) - (QuandaryConfig.Sink.of_json Config.quandary_sinks) - - - (* taint the nth parameter (0-indexed) *) - let taint_nth n kinds actuals = - if n < List.length actuals then - let indexes = IntSet.singleton n in - List.rev_map kinds ~f:(fun kind -> (kind, indexes)) - else [] - - - (* taint all parameters after the nth (exclusive) *) - let taint_after_nth n kinds actuals = - match - List.filter_mapi ~f:(fun actual_num _ -> Option.some_if (actual_num > n) actual_num) actuals - with - | [] -> - [] - | to_taint -> - let indexes = IntSet.of_list to_taint in - List.rev_map kinds ~f:(fun kind -> (kind, indexes)) - - - let taint_all kinds actuals = - let indexes = IntSet.of_list (List.mapi ~f:(fun actual_num _ -> actual_num) actuals) in - List.rev_map kinds ~f:(fun kind -> (kind, indexes)) - - - (* return Some(sink kinds) if [procedure_name] is in the list of externally specified sinks *) - let get_external_sink pname actuals = - let qualified_pname = Procname.get_qualifiers pname in - List.find_map - ~f:(fun (qualifiers, kinds, index) -> - if QualifiedCppName.Match.match_qualifiers qualifiers qualified_pname then - let kinds = List.rev_map ~f:of_string kinds in - try - let n = int_of_string index in - let taint = taint_nth n kinds actuals in - Option.some_if (not (List.is_empty taint)) taint - with Failure _ -> - (* couldn't parse the index, just taint everything *) - Some (taint_all kinds actuals) - else None ) - external_sinks - |> Option.value ~default:[] - - - let get pname actuals _ _ = - let is_buffer_like pname = - (* assume it's a buffer class if it's "vector-y", "array-y", or "string-y". don't want to - report on accesses to maps etc., but also want to recognize custom vectors like fbvector - rather than overfitting to std::vector *) - let typename = - Procname.get_qualifiers pname |> QualifiedCppName.strip_template_args - |> QualifiedCppName.to_qual_string |> String.lowercase - in - String.is_substring ~substring:"vec" typename - || String.is_substring ~substring:"array" typename - || String.is_substring ~substring:"string" typename - in - match pname with - | Procname.ObjC_Cpp cpp_name -> ( - match - ( QualifiedCppName.to_list - (Typ.Name.unqualified_name (Procname.ObjC_Cpp.get_class_type_name cpp_name)) - , Procname.get_method pname ) - with - | ( ["std"; ("basic_fstream" | "basic_ifstream" | "basic_ofstream")] - , ("basic_fstream" | "basic_ifstream" | "basic_ofstream" | "open") ) -> - taint_nth 1 [CreateFile] actuals - | _, "operator[]" when Config.developer_mode && is_buffer_like pname -> - taint_nth 1 [BufferAccess] actuals - | _ -> - get_external_sink pname actuals ) - | Procname.C _ - when String.is_substring ~substring:"SetCommandLineOption" (Procname.to_string pname) -> - taint_nth 1 [EnvironmentChange] actuals - | Procname.C _ when Config.developer_mode && Procname.equal pname BuiltinDecl.__array_access -> - taint_all [BufferAccess] actuals - | Procname.C _ when Procname.equal pname BuiltinDecl.__set_array_length -> - (* called when creating a stack-allocated array *) - taint_nth 1 [StackAllocation] actuals - | Procname.C _ -> ( - match Procname.to_string pname with - | "creat" | "fopen" | "freopen" | "open" -> - taint_nth 0 [CreateFile] actuals - | "curl_easy_setopt" -> ( - (* magic constant for setting request URL *) - let controls_request = function - | 10002 (* CURLOPT_URL *) | 10015 (* CURLOPT_POSTFIELDS *) -> - true - | _ -> - false - in - (* first two actuals are curl object + integer code for data kind. *) - match List.nth actuals 1 with - | Some exp -> ( - match HilExp.eval exp with - | Some (Const.Cint i) -> - (* check if the data kind might be CURLOPT_URL *) - IntLit.to_int i - |> Option.value_map ~default:[] ~f:(fun n -> - if controls_request n then taint_after_nth 1 [URL] actuals else [] ) - | _ -> - (* can't statically resolve data kind; taint it just in case *) - taint_after_nth 1 [URL] actuals ) - | None -> - [] ) - | "execl" | "execlp" | "execle" | "execv" | "execve" | "execvp" | "system" -> - taint_all [ShellExec] actuals - | "openat" -> - taint_nth 1 [CreateFile] actuals - | "popen" -> - taint_nth 0 [ShellExec] actuals - | "putenv" -> - taint_nth 0 [EnvironmentChange] actuals - | ("brk" | "calloc" | "malloc" | "realloc" | "sbrk") when Config.developer_mode -> - taint_all [HeapAllocation] actuals - | "rename" -> - taint_all [CreateFile] actuals - | "strcpy" when Config.developer_mode -> - (* warn if source array is tainted *) - taint_nth 1 [BufferAccess] actuals - | ("memcpy" | "memmove" | "memset" | "strncpy" | "wmemcpy" | "wmemmove") - when Config.developer_mode -> - (* warn if count argument is tainted *) - taint_nth 2 [BufferAccess] actuals - | _ -> - get_external_sink pname actuals ) - | Procname.Block _ -> - [] - | pname -> - L.(die InternalError) "Non-C++ procname %a in C++ analysis" Procname.pp pname - - - let pp fmt kind = - F.pp_print_string fmt - ( match kind with - | BufferAccess -> - "BufferAccess" - | CreateFile -> - "CreateFile" - | EnvironmentChange -> - "EnvironmentChange" - | HeapAllocation -> - "HeapAllocation" - | ShellExec -> - "ShellExec" - | SQLInjection -> - "SQLInjection" - | SQLRead -> - "SQLRead" - | SQLWrite -> - "SQLWrite" - | StackAllocation -> - "StackAllocation" - | URL -> - "URL" - | Other -> - "Other" ) -end - -module CppSink = Sink.Make (SinkKind) - -module CppSanitizer = struct - type t = - | EscapeShell (** escape string to sanitize shell commands *) - | EscapeSQL (** escape string to sanitize SQL queries *) - | EscapeURL (** escape string to sanitize URLs (e.g., prevent injecting GET/POST params) *) - | All (** sanitizes all forms of taint *) - [@@deriving compare, equal, show {with_path= false}] - - let of_string = function - | "EscapeShell" -> - EscapeShell - | "EscapeSQL" -> - EscapeSQL - | "EscapeURL" -> - EscapeURL - | _ -> - All - - - let external_sanitizers = - List.map - ~f:(fun {QuandaryConfig.Sanitizer.procedure; kind} -> - (QualifiedCppName.Match.of_fuzzy_qual_names [procedure], of_string kind) ) - (QuandaryConfig.Sanitizer.of_json Config.quandary_sanitizers) - - - let get pname _tenv = - let qualified_pname = Procname.get_qualifiers pname in - List.find_map - ~f:(fun (qualifiers, kind) -> - if QualifiedCppName.Match.match_qualifiers qualifiers qualified_pname then Some kind - else None ) - external_sanitizers -end - -include TaintTrace.Make (struct - module Source = CppSource - module Sink = CppSink - module Sanitizer = CppSanitizer - - (* return true if code injection is possible because the source is a string/is not sanitized with - [escape_sanitizer] *) - let is_injection_possible ?typ escape_sanitizer sanitizers = - let is_escaped = List.mem sanitizers escape_sanitizer ~equal:Sanitizer.equal in - (not is_escaped) - && - match typ with - | Some Typ.(Tint _ | Tfloat _ | Tvoid) -> - false - | _ -> - (* possible a string/object/struct type; assume injection possible *) - true - - - let get_report source sink sanitizers = - match (Source.kind source, Sink.kind sink) with - | _ when List.mem sanitizers Sanitizer.All ~equal:Sanitizer.equal -> - (* the All sanitizer clears any form of taint; don't report *) - None - | (Endpoint (_, typ) | UserControlledEndpoint (_, typ)), CreateFile -> - Option.some_if - (is_injection_possible ~typ Sanitizer.EscapeShell sanitizers) - IssueType.untrusted_file_risk - | (Endpoint (_, typ) | UserControlledEndpoint (_, typ)), URL -> - Option.some_if - (is_injection_possible ~typ Sanitizer.EscapeURL sanitizers) - IssueType.untrusted_url_risk - | (CommandLineFlag (_, typ) | Endpoint (_, typ) | UserControlledEndpoint (_, typ)), SQLInjection - -> - if is_injection_possible ~typ Sanitizer.EscapeSQL sanitizers then - Some IssueType.sql_injection_risk - else Some IssueType.user_controlled_sql_risk - | (Endpoint _ | UserControlledEndpoint _), (SQLRead | SQLWrite) -> - Some IssueType.user_controlled_sql_risk - | (Endpoint _ | UserControlledEndpoint _), EnvironmentChange -> - Some IssueType.untrusted_environment_change_risk - | (CommandLineFlag (_, typ) | Endpoint (_, typ) | UserControlledEndpoint (_, typ)), ShellExec -> - Option.some_if - (is_injection_possible ~typ Sanitizer.EscapeShell sanitizers) - IssueType.shell_injection_risk - | ( ( UserControlledEndpoint _ - | Endpoint _ - | CommandLineFlag _ - | EnvironmentVariable - | ReadFile - | Other ) - , BufferAccess ) -> - Some IssueType.untrusted_buffer_access - | (EnvironmentVariable | ReadFile | Other), ShellExec -> - Option.some_if - (is_injection_possible Sanitizer.EscapeShell sanitizers) - IssueType.shell_injection - | (EnvironmentVariable | ReadFile | Other), SQLInjection -> - (* untrusted flag, environment var, or file data flowing to SQL *) - Option.some_if - (is_injection_possible Sanitizer.EscapeSQL sanitizers) - IssueType.sql_injection - | Other, URL -> - Option.some_if - (is_injection_possible Sanitizer.EscapeURL sanitizers) - IssueType.untrusted_url_risk - | ( ( CommandLineFlag _ - | Endpoint _ - | UserControlledEndpoint _ - | EnvironmentVariable - | ReadFile - | Other ) - , HeapAllocation ) -> - Some IssueType.untrusted_heap_allocation - | ( ( CommandLineFlag _ - | Endpoint _ - | UserControlledEndpoint _ - | EnvironmentVariable - | ReadFile - | Other ) - , StackAllocation ) -> - Some IssueType.untrusted_variable_length_array - | ( (CommandLineFlag _ | EnvironmentVariable | ReadFile) - , (CreateFile | EnvironmentChange | SQLRead | SQLWrite | URL) ) -> - None - | Other, _ -> - (* Other matches everything *) - Some IssueType.quandary_taint_error - | _, Other -> - Some IssueType.quandary_taint_error -end) diff --git a/infer/src/quandary/ClangTrace.mli b/infer/src/quandary/ClangTrace.mli deleted file mode 100644 index 82d9193d6d9..00000000000 --- a/infer/src/quandary/ClangTrace.mli +++ /dev/null @@ -1,10 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd - -include TaintTrace.S diff --git a/infer/src/quandary/JavaTaintAnalysis.ml b/infer/src/quandary/JavaTaintAnalysis.ml deleted file mode 100644 index 555e8ebfa96..00000000000 --- a/infer/src/quandary/JavaTaintAnalysis.ml +++ /dev/null @@ -1,93 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd -module L = Logging - -include TaintAnalysis.Make (struct - module Trace = JavaTrace - module AccessTree = AccessTree.Make (Trace) (AccessTree.DefaultConfig) - - let to_summary_access_tree access_tree = QuandarySummary.AccessTree.Java access_tree - - let of_summary_access_tree = function - | QuandarySummary.AccessTree.Java access_tree -> - access_tree - | _ -> - assert false - - - let handle_unknown_call pname ret_typ actuals tenv = - let rec get_receiver_typ tenv = function - | HilExp.Cast (_, e) -> - get_receiver_typ tenv e - | HilExp.AccessExpression access_expr -> - AccessPath.get_typ (HilExp.AccessExpression.to_access_path access_expr) tenv - | _ -> - None - in - let types_match typ class_string tenv = - match typ with - | Some {Typ.desc= Typ.Tptr ({desc= Tstruct original_typename}, _)} -> - PatternMatch.supertype_exists tenv - (fun typename _ -> String.equal (Typ.Name.name typename) class_string) - original_typename - | _ -> - false - in - match pname with - | Procname.Java java_pname -> ( - let is_static = Procname.Java.is_static java_pname in - match - (Procname.Java.get_class_name java_pname, Procname.Java.get_method java_pname, ret_typ) - with - | "android.content.Intent", ("putExtra" | "putExtras"), _ -> - (* don't care about tainted extras. instead. we'll check that result of getExtra is - always used safely *) - [] - | _ when Procname.is_constructor pname -> - [TaintSpec.Propagate_to_receiver] - | _, _, {Typ.desc= Tvoid | Tint _ | Tfloat _} when not is_static -> - (* for instance methods with a non-Object return value, propagate the taint to the - receiver *) - [TaintSpec.Propagate_to_receiver] - | classname, _, {Typ.desc= Tptr _ | Tstruct _} -> ( - match actuals with - | receiver_exp :: _ - when (not is_static) && types_match (get_receiver_typ tenv receiver_exp) classname tenv - -> - (* if the receiver and return type are the same, propagate to both. we're - assuming the call is one of the common "builder-style" methods that both - updates and returns the receiver *) - [TaintSpec.Propagate_to_receiver; TaintSpec.Propagate_to_return] - | _ -> - (* receiver doesn't match return type; just propagate to the return type *) - [TaintSpec.Propagate_to_return] ) - | _ -> - [] ) - | pname when BuiltinDecl.is_declared pname -> - [] - | pname -> - L.(die InternalError) "Non-Java procname %a in Java analysis" Procname.pp pname - - - let get_model _ _ _ _ _ = None - - let is_taintable_type typ = - match typ.Typ.desc with - | Typ.Tptr ({desc= Tstruct (JavaClass typename)}, _) | Tstruct (JavaClass typename) -> ( - match JavaClassName.to_string typename with - | "android.content.Intent" | "android.net.Uri" | "java.lang.String" | "java.net.URI" -> - true - | _ -> - false ) - | _ -> - false - - - let name = "java" -end) diff --git a/infer/src/quandary/JavaTaintAnalysis.mli b/infer/src/quandary/JavaTaintAnalysis.mli deleted file mode 100644 index ca77632a235..00000000000 --- a/infer/src/quandary/JavaTaintAnalysis.mli +++ /dev/null @@ -1,10 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd - -val checker : QuandarySummary.t InterproceduralAnalysis.t -> QuandarySummary.t option diff --git a/infer/src/quandary/JavaTrace.ml b/infer/src/quandary/JavaTrace.ml deleted file mode 100644 index 5bbe362276e..00000000000 --- a/infer/src/quandary/JavaTrace.ml +++ /dev/null @@ -1,624 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd -module F = Format -module L = Logging - -module SourceKind = struct - type t = - | DrawableResource of Pvar.t (** Drawable resource ID read from a global *) - | Endpoint of (Mangled.t * Typ.desc) (** source originating from formal of an endpoint *) - | Intent (** external Intent or a value read from one *) - | IntentForInsecureIntentHandling of {exposed: bool} - | IntentFromURI (** Intent created from a URI *) - | Other (** for testing or uncategorized sources *) - | PrivateData (** private user or device-specific data *) - | UserControlledString (** data read from a text box or the clipboard service *) - | UserControlledURI (** resource locator originating from the browser bar *) - [@@deriving compare, equal] - - let is_exposed ~caller_pname = - match caller_pname with - | Procname.Java java_pname -> - let class_name = Procname.Java.get_class_name java_pname in - QuandaryConfig.is_endpoint class_name - | _ -> - false - - - let intent_for_insecure_intent_handling ~caller_pname = - let exposed = is_exposed ~caller_pname in - IntentForInsecureIntentHandling {exposed} - - - let matches ~caller ~callee = Int.equal 0 (compare caller callee) - - let of_string = function - | "Endpoint" -> - Endpoint (Mangled.from_string "NONE", Typ.Tvoid) - | "Intent" -> - Intent - | "IntentFromURI" -> - IntentFromURI - | "PrivateData" -> - PrivateData - | "UserControlledURI" -> - UserControlledURI - | "UserControlledString" -> - UserControlledString - | _ -> - Other - - - let external_sources = - List.map - ~f:(fun {QuandaryConfig.Source.procedure; kinds} -> (Str.regexp procedure, kinds)) - (QuandaryConfig.Source.of_json Config.quandary_sources) - - - let actual_has_type n type_string actuals tenv = - let is_typ typename _ = String.equal (Typ.Name.name typename) type_string in - match List.nth actuals n with - | Some actual -> ( - match HilExp.get_typ tenv actual with - | Some {desc= Tptr ({desc= Tstruct typename}, _)} -> - PatternMatch.supertype_exists tenv is_typ typename - | _ -> - false ) - | None -> - false - - - let get ~caller_pname pname actuals tenv = - let return = None in - let get_external_source class_name method_name = - (* check the list of externally specified sources *) - let procedure = class_name ^ "." ^ method_name in - let sources = - List.concat_map external_sources ~f:(fun (procedure_regex, kinds) -> - if Str.string_match procedure_regex procedure 0 then - List.rev_map kinds ~f:(fun kind -> (of_string kind, return)) - else [] ) - in - Option.some_if (not (List.is_empty sources)) sources - in - match pname with - | Procname.Java pname -> - let method_name = Procname.Java.get_method pname in - let taint_matching_supertype typename = - match (Typ.Name.name typename, method_name) with - | "android.app.Activity", "getIntent" -> - Some [(Intent, return); (intent_for_insecure_intent_handling ~caller_pname, return)] - | "android.support.v4.app.FragmentActivity", "getIntent" -> - Some [(intent_for_insecure_intent_handling ~caller_pname, return)] - | "android.content.Intent", "" when actual_has_type 2 "android.net.Uri" actuals tenv - -> - (* taint the [this] parameter passed to the constructor *) - Some [(IntentFromURI, Some 0)] - | ( "android.content.Intent" - , ( "parseUri" - | "setData" - | "setDataAndNormalize" - | "setDataAndType" - | "setDataAndTypeAndNormalize" ) ) -> - Some [(IntentFromURI, return)] - | "android.content.Intent", "getData" -> - Some [(intent_for_insecure_intent_handling ~caller_pname, return)] - | "android.content.Intent", "getStringExtra" -> - Some [(Intent, return)] - | "android.content.SharedPreferences", "getString" -> - Some [(PrivateData, return)] - | ( ("android.content.ClipboardManager" | "android.text.ClipboardManager") - , ("getPrimaryClip" | "getText") ) -> - Some [(UserControlledString, return)] - | ( "android.location.Location" - , ("getAltitude" | "getBearing" | "getLatitude" | "getLongitude" | "getSpeed") ) -> - Some [(PrivateData, return)] - | ( "android.telephony.TelephonyManager" - , ( "getDeviceId" - | "getLine1Number" - | "getSimSerialNumber" - | "getSubscriberId" - | "getVoiceMailNumber" ) ) -> - Some [(PrivateData, return)] - | "android.webkit.WebResourceRequest", "getUrl" -> - Some [(UserControlledURI, return)] - | "android.widget.EditText", "getText" -> - Some [(UserControlledString, return)] - | "com.facebook.infer.builtins.InferTaint", "inferSecretSource" -> - Some [(Other, return)] - | class_name, method_name -> - get_external_source class_name method_name - in - PatternMatch.supertype_find_map_opt tenv taint_matching_supertype - (Procname.Java.get_class_type_name pname) - |> Option.value ~default:[] - | Procname.C _ when Procname.equal pname BuiltinDecl.__global_access -> ( - (* accessed global will be passed to us as the only parameter *) - match List.map actuals ~f:HilExp.ignore_cast with - | [HilExp.AccessExpression access_expr] -> ( - match HilExp.AccessExpression.to_access_path access_expr with - | (Var.ProgramVar pvar, _), _ -> - let pvar_string = Pvar.to_string pvar in - (* checking substring instead of prefix because we expect field names like - com.myapp.R$drawable.whatever *) - if String.is_substring ~substring:AndroidFramework.drawable_prefix pvar_string then - [(DrawableResource pvar, None)] - else [] - | _ -> - [] ) - | _ -> - [] ) - | pname when BuiltinDecl.is_declared pname -> - [] - | pname -> - L.(die InternalError) "Non-Java procname %a in Java analysis" Procname.pp pname - - - let get_tainted_formals pdesc tenv = - let make_untainted (name, typ, _) = (name, typ, None) in - let taint_formals_with_types type_strs kind formals = - let taint_formal_with_types ((formal_name, formal_typ, _) as formal) = - let matches_classname = - match formal_typ.Typ.desc with - | Tptr ({desc= Tstruct typename}, _) -> - List.mem ~equal:String.equal type_strs (Typ.Name.name typename) - | _ -> - false - in - if matches_classname then (formal_name, formal_typ, Some kind) else make_untainted formal - in - List.map ~f:taint_formal_with_types formals - in - (* taint all formals except for [this] *) - let taint_all_but_this ~make_source = - List.map - ~f:(fun (name, typ, _) -> - let taint = if Mangled.is_this name then None else Some (make_source name typ.Typ.desc) in - (name, typ, taint) ) - (Procdesc.get_formals pdesc) - in - let formals = Procdesc.get_formals pdesc in - match Procdesc.get_proc_name pdesc with - | Procname.Java java_pname as pname -> ( - let method_name = Procname.Java.get_method java_pname in - let taint_matching_supertype typename = - match (Typ.Name.name typename, method_name) with - | ( ( "android.app.Activity" - | "android.app.Fragment" - | "android.support.v4.app.Fragment" - | "androidx.fragment.app.Fragment" ) - , ("onActivityResult" | "onNewIntent") ) -> - Some (taint_formals_with_types ["android.content.Intent"] Intent formals) - | ( "android.app.Service" - , ("onBind" | "onRebind" | "onStart" | "onStartCommand" | "onTaskRemoved" | "onUnbind") - ) -> - Some (taint_formals_with_types ["android.content.Intent"] Intent formals) - | "android.content.BroadcastReceiver", "onReceive" -> - Some (taint_formals_with_types ["android.content.Intent"] Intent formals) - | ( "android.content.ContentProvider" - , ( "bulkInsert" - | "call" - | "delete" - | "insert" - | "getType" - | "openAssetFile" - | "openFile" - | "openPipeHelper" - | "openTypedAssetFile" - | "query" - | "refresh" - | "update" ) ) -> - Some - (taint_formals_with_types - ["android.net.Uri"; "java.lang.String"] - UserControlledURI formals ) - | ( "android.webkit.WebChromeClient" - , ("onJsAlert" | "onJsBeforeUnload" | "onJsConfirm" | "onJsPrompt") ) -> - Some (taint_formals_with_types ["java.lang.String"] UserControlledURI formals) - | ( "android.webkit.WebViewClient" - , ("onLoadResource" | "shouldInterceptRequest" | "shouldOverrideUrlLoading") ) -> - Some - (taint_formals_with_types - ["android.webkit.WebResourceRequest"; "java.lang.String"] - UserControlledURI formals ) - | "codetoanalyze.java.quandary.TaintedFormals", "taintedContextBad" -> - Some - (taint_formals_with_types ["java.lang.Integer"; "java.lang.String"] Other formals) - | _ -> ( - match Tenv.lookup tenv typename with - | Some typ -> - if - Annotations.struct_typ_has_annot typ Annotations.ia_is_thrift_service - && PatternMatch.override_exists ~check_current_type:false - (fun superclass_pname -> - String.equal (Procname.get_method superclass_pname) method_name ) - tenv pname - then - (* assume every non-this formal of a Thrift service is tainted *) - (* TODO: may not want to taint numbers or Enum's *) - Some (taint_all_but_this ~make_source:(fun name desc -> Endpoint (name, desc))) - else None - | _ -> - None ) - in - match - PatternMatch.supertype_find_map_opt tenv taint_matching_supertype - (Procname.Java.get_class_type_name java_pname) - with - | Some tainted_formals -> - tainted_formals - | None -> - Source.all_formals_untainted pdesc ) - | procname -> - L.(die InternalError) - "Non-Java procedure %a where only Java procedures are expected" Procname.pp procname - - - let pp fmt kind = - match kind with - | DrawableResource pvar -> - F.pp_print_string fmt (Pvar.to_string pvar) - | Endpoint (formal_name, _) -> - F.fprintf fmt "Endpoint(%s)" (Mangled.to_string formal_name) - | Intent | IntentForInsecureIntentHandling _ -> - F.pp_print_string fmt "Intent" - | IntentFromURI -> - F.pp_print_string fmt "IntentFromURI" - | Other -> - F.pp_print_string fmt "Other" - | PrivateData -> - F.pp_print_string fmt "PrivateData" - | UserControlledString -> - F.pp_print_string fmt "UserControlledString" - | UserControlledURI -> - F.pp_print_string fmt "UserControlledURI" -end - -module JavaSource = Source.Make (SourceKind) - -module SinkKind = struct - type t = - | ClassLoading - | CreateFile (** sink that creates a file *) - | CreateIntent (** sink that creates an Intent *) - | OpenDrawableResource (** sink that inflates a Drawable resource from an integer ID *) - | Deserialization (** sink that deserializes a Java object *) - | HTML (** sink that creates HTML *) - | JavaScript (** sink that passes its arguments to untrusted JS code *) - | Logging (** sink that logs one or more of its arguments *) - | ShellExec (** sink that runs a shell command *) - | SQLInjection (** unescaped query to a SQL database (could be a read or a write) *) - | SQLRead (** escaped read to a SQL database *) - | SQLWrite (** escaped write to a SQL database *) - | StartComponent (** sink that launches an Activity, Service, etc. *) - | StartComponentForInsecureIntentHandling - | Other (** for testing or uncategorized sinks *) - [@@deriving compare, equal] - - let matches ~caller ~callee = Int.equal 0 (compare caller callee) - - let of_string = function - | "ClassLoading" -> - ClassLoading - | "CreateFile" -> - CreateFile - | "CreateIntent" -> - CreateIntent - | "Deserialization" -> - Deserialization - | "HTML" -> - HTML - | "JavaScript" -> - JavaScript - | "Logging" -> - Logging - | "OpenDrawableResource" -> - OpenDrawableResource - | "ShellExec" -> - ShellExec - | "SQLInjection" -> - SQLInjection - | "SQLRead" -> - SQLRead - | "SQLWrite" -> - SQLWrite - | "StartComponent" -> - StartComponent - | "StartComponentForInsecureIntentHandling" -> - StartComponentForInsecureIntentHandling - | _ -> - Other - - - let external_sinks = - List.map - ~f:(fun {QuandaryConfig.Sink.procedure; kinds; index} -> (Str.regexp procedure, kinds, index)) - (QuandaryConfig.Sink.of_json Config.quandary_sinks) - - - let get pname actuals _ tenv = - match pname with - | Procname.Java java_pname -> - (* taint all the inputs of [pname]. for non-static procedures, taints the "this" parameter - only if [taint_this] is true. *) - let taint_all ?(taint_this = false) kinds = - let actuals_to_taint, offset = - if Procname.Java.is_static java_pname || taint_this then (actuals, 0) - else (List.tl_exn actuals, 1) - in - let indexes = - IntSet.of_list (List.mapi ~f:(fun param_num _ -> param_num + offset) actuals_to_taint) - in - Some (List.rev_map kinds ~f:(fun kind -> (kind, indexes))) - in - (* taint the nth non-"this" parameter (0-indexed) *) - let taint_nth n kinds = - let first_index = if Procname.Java.is_static java_pname then n else n + 1 in - if first_index < List.length actuals then - let first_index = IntSet.singleton first_index in - Some (List.rev_map kinds ~f:(fun kind -> (kind, first_index))) - else None - in - let get_external_sink class_name method_name = - (* check the list of externally specified sinks *) - let procedure = class_name ^ "." ^ method_name in - let sinks = - List.concat_map external_sinks ~f:(fun (procedure_regex, kinds, index) -> - if Str.string_match procedure_regex procedure 0 then - let kinds = List.rev_map ~f:of_string kinds in - let taints = - try - let n = int_of_string index in - taint_nth n kinds - with Failure _ -> - (* couldn't parse the index, just taint everything *) - taint_all kinds - in - Option.value taints ~default:[] - else [] ) - in - Option.some_if (not (List.is_empty sinks)) sinks - in - let method_name = Procname.Java.get_method java_pname in - let taint_matching_supertype typename = - match (Typ.Name.name typename, method_name) with - | "android.app.Activity", ("startActivityFromChild" | "startActivityFromFragment") -> - taint_nth 1 [StartComponent] - | ( ( "android.app.Activity" - | "android.content.Context" - | "android.support.v4.app.Fragment" - | "androidx.fragment.app.Fragment" ) - , "startIntentSenderForResult" ) -> - taint_nth 2 [StartComponent] - | "android.app.Activity", "startIntentSenderFromChild" -> - taint_nth 3 [StartComponent] - | ( ( "android.app.Fragment" - | "android.content.Context" - | "android.support.v4.app.Fragment" - | "androidx.fragment.app.Fragment" ) - , "startActivity" ) -> - taint_nth 0 [StartComponent; StartComponentForInsecureIntentHandling] - | ( ( "android.app.Fragment" - | "android.content.Context" - | "android.support.v4.app.Fragment" - | "androidx.fragment.app.Fragment" ) - , ( "bindService" - | "sendBroadcast" - | "sendBroadcastAsUser" - | "sendOrderedBroadcast" - | "sendOrderedBroadcastAsUser" - | "sendStickyBroadcast" - | "sendStickyBroadcastAsUser" - | "sendStickyOrderedBroadcast" - | "sendStickyOrderedBroadcastAsUser" - | "startActivities" - | "startActivityForResult" - | "startActivityIfNeeded" - | "startNextMatchingActivity" - | "startService" - | "stopService" ) ) -> - taint_nth 0 [StartComponent] - | "android.content.Context", "startIntentSender" -> - taint_nth 1 [StartComponent] - | ( "android.content.Intent" - , ( "parseUri" - | "getIntent" - | "getIntentOld" - | "setComponent" - | "setData" - | "setDataAndNormalize" - | "setDataAndType" - | "setDataAndTypeAndNormalize" - | "setPackage" ) ) -> - taint_nth 0 [CreateIntent] - | "android.content.Intent", "setClassName" -> - taint_all [CreateIntent] - | "android.text.Html", "fromHtml" -> - taint_nth 0 [HTML] - | "android.util.Log", ("e" | "println" | "w" | "wtf") -> - taint_all [Logging] - | ( "android.webkit.WebView" - , ( "evaluateJavascript" - | "loadData" - | "loadDataWithBaseURL" - | "loadUrl" - | "postUrl" - | "postWebMessage" ) ) -> - taint_all [JavaScript] - | "com.facebook.infer.builtins.InferTaint", "inferSensitiveSink" -> - taint_nth 0 [Other] - | "java.io.File", "" - | "java.nio.file.FileSystem", "getPath" - | "java.nio.file.Paths", "get" -> - taint_all [CreateFile] - | "java.io.ObjectInputStream", "" -> - taint_all [Deserialization] - | "java.lang.Class", "forName" | "java.lang.ClassLoader", "loadClass" -> - taint_nth 0 [ClassLoading] - | "java.lang.ClassLoader", "defineClass" -> - taint_nth 1 [ClassLoading] - | "java.lang.ProcessBuilder", "" -> - taint_all [ShellExec] - | "java.lang.ProcessBuilder", "command" -> - taint_all [ShellExec] - | "java.lang.Runtime", "exec" -> - taint_nth 0 [ShellExec] - (* TODO: separate non-injection sinks for PreparedStatement's *) - | "java.sql.Statement", ("addBatch" | "execute") -> - taint_nth 0 [SQLInjection] - | "java.sql.Statement", "executeQuery" -> - taint_nth 0 [SQLRead] - | "java.sql.Statement", ("executeUpdate" | "executeLargeUpdate") -> - taint_nth 0 [SQLWrite] - | class_name, method_name -> - get_external_sink class_name method_name - in - PatternMatch.supertype_find_map_opt tenv taint_matching_supertype - (Procname.Java.get_class_type_name java_pname) - |> Option.value ~default:[] - | pname when BuiltinDecl.is_declared pname -> - [] - | pname -> - L.(die InternalError) "Non-Java procname %a in Java analysis" Procname.pp pname - - - let pp fmt kind = - F.fprintf fmt - ( match kind with - | ClassLoading -> - "ClassLoading" - | CreateFile -> - "CreateFile" - | CreateIntent -> - "CreateIntent" - | Deserialization -> - "Deserialization" - | HTML -> - "HTML" - | JavaScript -> - "JavaScript" - | Logging -> - "Logging" - | OpenDrawableResource -> - "OpenDrawableResource" - | ShellExec -> - "ShellExec" - | SQLInjection -> - "SQLInjection" - | SQLRead -> - "SQLRead" - | SQLWrite -> - "SQLWrite" - | StartComponent | StartComponentForInsecureIntentHandling -> - "StartComponent" - | Other -> - "Other" ) -end - -module JavaSink = Sink.Make (SinkKind) - -module JavaSanitizer = struct - type t = All | StringConcatenation [@@deriving compare, equal] - - let external_sanitizers = - List.map - ~f:(fun {QuandaryConfig.Sanitizer.procedure} -> Str.regexp procedure) - (QuandaryConfig.Sanitizer.of_json Config.quandary_sanitizers) - - - let get_external_sanitizer class_name method_name = - let procedure_string = Printf.sprintf "%s.%s" class_name method_name in - List.find_map - ~f:(fun procedure_regex -> - if Str.string_match procedure_regex procedure_string 0 then Some All else None ) - external_sanitizers - - - let get pname tenv = - match pname with - | Procname.Java java_pname -> - let method_name = Procname.Java.get_method java_pname in - let sanitizer_matching_supertype typename = - match (Typ.Name.name typename, method_name) with - (* string concatenation is translated differently by invokedynamic in JDK11 *) - | "java.lang.Object", "makeConcatWithConstants" -> - Some StringConcatenation - | "java.lang.StringBuilder", "append" -> - Some StringConcatenation - | class_name, method_name -> - get_external_sanitizer class_name method_name - in - PatternMatch.supertype_find_map_opt tenv sanitizer_matching_supertype - (Procname.Java.get_class_type_name java_pname) - | _ -> - None - - - let pp fmt kind = - F.pp_print_string fmt - (match kind with All -> "All" | StringConcatenation -> "StringConcatenation") -end - -include TaintTrace.Make (struct - module Source = JavaSource - module Sink = JavaSink - module Sanitizer = JavaSanitizer - - let get_report source sink sanitizers = - match (Source.kind source, Sink.kind sink) with - | _ when List.mem sanitizers Sanitizer.All ~equal:Sanitizer.equal -> - (* the All sanitizer clears any form of taint; don't report *) - None - | _, ClassLoading when List.mem sanitizers Sanitizer.StringConcatenation ~equal:Sanitizer.equal - -> - None - | (Endpoint _ | Intent | UserControlledString | UserControlledURI), CreateIntent -> - Some IssueType.untrusted_intent_creation - | (Intent | IntentFromURI | UserControlledString | UserControlledURI), CreateFile -> - Some IssueType.untrusted_file - | Endpoint _, CreateFile -> - Some IssueType.untrusted_file_risk - | (Intent | IntentFromURI | UserControlledString | UserControlledURI), Deserialization -> - Some IssueType.untrusted_deserialization - | Endpoint _, Deserialization -> - Some IssueType.untrusted_deserialization_risk - | (Endpoint _ | Intent | IntentFromURI | UserControlledString | UserControlledURI), HTML -> - Some IssueType.cross_site_scripting - | (Endpoint _ | Intent | IntentFromURI | UserControlledString | UserControlledURI), JavaScript - -> - Some IssueType.javascript_injection - | (Endpoint _ | Intent | IntentFromURI | UserControlledString | UserControlledURI), SQLInjection - -> - Some IssueType.sql_injection_risk - | ( (Endpoint _ | Intent | IntentFromURI | UserControlledString | UserControlledURI) - , (SQLRead | SQLWrite) ) -> - Some IssueType.user_controlled_sql_risk - | DrawableResource _, OpenDrawableResource -> - (* not a security issue, but useful for debugging flows from resource IDs to inflation *) - Some IssueType.quandary_taint_error - | IntentForInsecureIntentHandling {exposed= true}, StartComponentForInsecureIntentHandling -> - Some IssueType.exposed_insecure_intent_handling - | IntentForInsecureIntentHandling {exposed= false}, StartComponentForInsecureIntentHandling -> - Some IssueType.insecure_intent_handling - | IntentFromURI, StartComponent -> - Some IssueType.create_intent_from_uri - | PrivateData, Logging -> - Some IssueType.logging_private_data - | (Intent | UserControlledString | UserControlledURI), (ClassLoading | ShellExec) -> - Some IssueType.shell_injection - | Endpoint _, (ClassLoading | ShellExec) -> - Some IssueType.shell_injection_risk - | Other, _ | _, Other -> - (* for testing purposes, Other matches everything *) - Some IssueType.quandary_taint_error - | (DrawableResource _ | IntentForInsecureIntentHandling _ | IntentFromURI | PrivateData), _ - | _, (Logging | OpenDrawableResource | StartComponent | StartComponentForInsecureIntentHandling) - -> - None -end) diff --git a/infer/src/quandary/JavaTrace.mli b/infer/src/quandary/JavaTrace.mli deleted file mode 100644 index 82d9193d6d9..00000000000 --- a/infer/src/quandary/JavaTrace.mli +++ /dev/null @@ -1,10 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd - -include TaintTrace.S diff --git a/infer/src/quandary/QuandaryConfig.ml b/infer/src/quandary/QuandaryConfig.ml deleted file mode 100644 index 0e62317dd76..00000000000 --- a/infer/src/quandary/QuandaryConfig.ml +++ /dev/null @@ -1,88 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd - -(** utilities for importing JSON specifications of sources/sinks into Quandary *) - -let get_kinds json = - let open Yojson.Safe in - match (Util.member "kinds" json, Util.member "kind" json) with - | `Null, kind -> - [Util.to_string kind] - | kinds, kind -> - (Util.to_string_option kind |> Option.to_list) @ Util.convert_each Util.to_string kinds - - -module Source = struct - type t = {procedure: string; kinds: string list; index: string} - - let of_json = function - | `List sources -> - let parse_source json = - let open Yojson.Safe in - let procedure = Util.member "procedure" json |> Util.to_string in - let kinds = get_kinds json in - let index = - Util.member "index" json |> Util.to_string_option |> Option.value ~default:"return" - in - {procedure; kinds; index} - in - List.map ~f:parse_source sources - | _ -> - [] -end - -module Sink = struct - type t = {procedure: string; kinds: string list; index: string} - - let of_json = function - | `List sinks -> - let parse_sink json = - let open Yojson.Safe in - let procedure = Util.member "procedure" json |> Util.to_string in - let kinds = get_kinds json in - let index = - Util.member "index" json |> Util.to_string_option |> Option.value ~default:"all" - in - {procedure; kinds; index} - in - List.map ~f:parse_sink sinks - | _ -> - [] -end - -module Sanitizer = struct - type t = {procedure: string; kind: string} - - let of_json = function - | `List sinks -> - let parse_sanitizer json = - let open Yojson.Safe in - let procedure = Util.member "procedure" json |> Util.to_string in - let kind = - Util.member "kind" json |> Util.to_string_option |> Option.value ~default:"All" - in - {procedure; kind} - in - List.map ~f:parse_sanitizer sinks - | _ -> - [] -end - -module Endpoints = struct - let of_json = function - | `List endpoints -> - let parse_endpoint = Yojson.Safe.Util.to_string in - List.map ~f:parse_endpoint endpoints - | _ -> - [] -end - -let is_endpoint = - let endpoints = lazy (String.Set.of_list (Endpoints.of_json Config.quandary_endpoints)) in - fun name -> String.Set.mem (Lazy.force endpoints) name diff --git a/infer/src/quandary/QuandaryConfig.mli b/infer/src/quandary/QuandaryConfig.mli deleted file mode 100644 index 40dbf3b3b03..00000000000 --- a/infer/src/quandary/QuandaryConfig.mli +++ /dev/null @@ -1,30 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd - -(** utilities for importing JSON specifications of sources/sinks into Quandary*) - -module Source : sig - type t = {procedure: string; kinds: string list; index: string} - - val of_json : [> `List of Yojson.Safe.t list] -> t list -end - -module Sink : sig - type t = {procedure: string; kinds: string list; index: string} - - val of_json : [> `List of Yojson.Safe.t list] -> t list -end - -module Sanitizer : sig - type t = {procedure: string; kind: string} - - val of_json : [> `List of Yojson.Safe.t list] -> t list -end - -val is_endpoint : string -> bool diff --git a/infer/src/quandary/QuandarySummary.ml b/infer/src/quandary/QuandarySummary.ml deleted file mode 100644 index fa7e340ef9e..00000000000 --- a/infer/src/quandary/QuandarySummary.ml +++ /dev/null @@ -1,27 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -(** summary type for Quandary taint analysis *) - -open! IStd -module F = Format -module Java = AccessTree.Make (JavaTrace) (AccessTree.DefaultConfig) -module Clang = AccessTree.Make (ClangTrace) (AccessTree.DefaultConfig) - -module AccessTree = struct - type t = Java of Java.t | Clang of Clang.t - - let pp fmt = function - | Java access_tree -> - Java.pp fmt access_tree - | Clang access_tree -> - Clang.pp fmt access_tree -end - -type t = AccessTree.t - -let pp = AccessTree.pp diff --git a/infer/src/quandary/QuandarySummary.mli b/infer/src/quandary/QuandarySummary.mli deleted file mode 100644 index 886c2e4e4e2..00000000000 --- a/infer/src/quandary/QuandarySummary.mli +++ /dev/null @@ -1,24 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd - -(** summary type for Quandary taint analysis *) - -module F = Format - -module Java : module type of AccessTree.Make (JavaTrace) (AccessTree.DefaultConfig) - -module Clang : module type of AccessTree.Make (ClangTrace) (AccessTree.DefaultConfig) - -module AccessTree : sig - type t = Java of Java.t | Clang of Clang.t -end - -type t = AccessTree.t - -val pp : F.formatter -> t -> unit diff --git a/infer/src/quandary/TaintAnalysis.ml b/infer/src/quandary/TaintAnalysis.ml deleted file mode 100644 index 7ae15d9626a..00000000000 --- a/infer/src/quandary/TaintAnalysis.ml +++ /dev/null @@ -1,854 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd -module F = Format -module L = Logging - -(** Create a taint analysis from a specification *) -module Make (TaintSpecification : TaintSpec.S) = struct - module TraceDomain = TaintSpecification.Trace - module TaintDomain = TaintSpecification.AccessTree - module Domain = TaintDomain - - type analysis_data = - {analysis_data: QuandarySummary.t InterproceduralAnalysis.t; formal_map: FormalMap.t} - - module TransferFunctions (CFG : ProcCfg.S) = struct - module CFG = CFG - module Domain = Domain - - type nonrec analysis_data = analysis_data - - (* get the node associated with [access_path] in [access_tree] *) - let access_path_get_node access_path access_tree formal_map = - match TaintDomain.get_node access_path access_tree with - | Some _ as node_opt -> - node_opt - | None -> ( - let make_footprint_trace footprint_ap = - let trace = TraceDomain.of_footprint footprint_ap in - Some (TaintDomain.make_normal_leaf trace) - in - let root, _ = AccessPath.Abs.extract access_path in - match FormalMap.get_formal_index root formal_map with - | Some formal_index -> - make_footprint_trace (AccessPath.Abs.to_footprint formal_index access_path) - | None -> - if Var.is_global (fst root) then make_footprint_trace access_path else None ) - - - (* get the trace associated with [access_path] in [access_tree]. *) - let access_path_get_trace access_path access_tree formal_map = - match access_path_get_node access_path access_tree formal_map with - | Some (trace, _) -> - trace - | None -> - TraceDomain.bottom - - - let exp_get_node_ ~abstracted raw_access_path access_tree formal_map = - let access_path = - if abstracted then AccessPath.Abs.Abstracted raw_access_path - else AccessPath.Abs.Exact raw_access_path - in - access_path_get_node access_path access_tree formal_map - - - (* get the node associated with [exp] in [access_tree] *) - let rec hil_exp_get_node ?(abstracted = false) (exp : HilExp.t) access_tree formal_map = - match exp with - | AccessExpression access_expr -> - exp_get_node_ ~abstracted - (HilExp.AccessExpression.to_access_path access_expr) - access_tree formal_map - | Cast (_, e) | Exception e | UnaryOperator (_, e, _) -> - hil_exp_get_node ~abstracted e access_tree formal_map - | BinaryOperator (_, e1, e2) -> ( - match - ( hil_exp_get_node ~abstracted e1 access_tree formal_map - , hil_exp_get_node ~abstracted e2 access_tree formal_map ) - with - | Some node1, Some node2 -> - Some (TaintDomain.node_join node1 node2) - | node_opt, None | None, node_opt -> - node_opt ) - | _ -> - None - - - let add_return_source source ret_base access_tree = - let trace = TraceDomain.of_source source in - let id_ap = AccessPath.Abs.Abstracted (ret_base, []) in - TaintDomain.add_trace id_ap trace access_tree - - - let add_actual_source source index actuals access_tree formal_map = - match HilExp.ignore_cast (List.nth_exn actuals index) with - | HilExp.AccessExpression actual_ae_raw -> - let actual_ap = - AccessPath.Abs.Abstracted (HilExp.AccessExpression.to_access_path actual_ae_raw) - in - let trace = access_path_get_trace actual_ap access_tree formal_map in - TaintDomain.add_trace actual_ap (TraceDomain.add_source source trace) access_tree - | _ -> - access_tree - | exception Failure s -> - L.internal_error - "Bad source specification: index %d out of bounds (%s) for source %a, actuals %a" index - s TraceDomain.Source.pp source - (PrettyPrintable.pp_collection ~pp_item:HilExp.pp) - actuals ; - access_tree - - - let is_endpoint source = - match CallSite.pname (TraceDomain.Source.call_site source) with - | Procname.Java java_pname -> - QuandaryConfig.is_endpoint (Procname.Java.get_class_name java_pname) - | _ -> - false - - - (** log any new reportable source-sink flows in [trace] *) - let report_trace {InterproceduralAnalysis.proc_desc; err_log; analyze_dependency} - ?(sink_indexes = IntSet.empty) trace cur_site = - let get_summary pname = - if Procname.equal pname (Procdesc.get_proc_name proc_desc) then - (* read_summary will trigger ondemand analysis of the current proc. we don't want that. *) - TaintDomain.bottom - else - match analyze_dependency pname with - | Ok summary -> - TaintSpecification.of_summary_access_tree summary - | Error _ -> - TaintDomain.bottom - in - let get_caller_string caller_site = - let caller_pname = CallSite.pname caller_site in - F.sprintf " in procedure %s" (Procname.to_simplified_string ~withclass:true caller_pname) - in - let pp_trace_elem site fmt caller_string = - F.fprintf fmt "(%s)%s at %a" - (Procname.to_simplified_string ~withclass:true (CallSite.pname site)) - caller_string Location.pp (CallSite.loc site) - in - let pp_source source_caller_opt fmt initial_source = - let source_caller_string = - match source_caller_opt with - | Some source_caller -> - get_caller_string (TraceDomain.Source.call_site source_caller) - | None -> - "" - in - F.fprintf fmt "%a%a" TraceDomain.Source.Kind.pp - (TraceDomain.Source.kind initial_source) - (pp_trace_elem (TraceDomain.Source.call_site initial_source)) - source_caller_string - in - let pp_sink sink_caller_opt fmt final_sink = - let sink_caller_string = - match sink_caller_opt with - | Some sink_caller -> - get_caller_string (TraceDomain.Sink.call_site sink_caller) - | None -> - "" - in - F.fprintf fmt "%a%a" TraceDomain.Sink.Kind.pp - (TraceDomain.Sink.kind final_sink) - (pp_trace_elem (TraceDomain.Sink.call_site final_sink)) - sink_caller_string - in - let get_short_trace_string initial_source source_caller_opt final_sink sink_caller_opt = - F.asprintf "%a ~> %a%s" (pp_source source_caller_opt) initial_source - (pp_sink sink_caller_opt) final_sink - (if is_endpoint initial_source then ". Note: source is an endpoint." else "") - in - let report_one {TraceDomain.issue; path_source; path_sink} = - let open TraceDomain in - let rec expand_source source0 ((report_acc, seen_acc) as acc) = - let kind = Source.kind source0 in - let call_site = Source.call_site source0 in - let seen_acc' = CallSite.Set.add call_site seen_acc in - let is_recursive source = CallSite.Set.mem (Source.call_site source) seen_acc' in - let matching_sources = - (* TODO: group by matching call sites, remember all access paths *) - TaintDomain.trace_fold - (fun acc access_path trace -> - match - List.find - ~f:(fun source -> - Source.Kind.equal kind (Source.kind source) && not (is_recursive source) ) - (Sources.Known.elements (sources trace).Sources.known) - with - | Some matching_source -> - (Some access_path, matching_source) :: acc - | None -> - acc ) - (get_summary (CallSite.pname call_site)) - [] - in - match matching_sources with - | ((_, matching_source) as choice) :: _ -> - expand_source matching_source (choice :: report_acc, seen_acc') - | [] -> - acc - in - let rec expand_sink sink0 indexes0 ((report_acc, seen_acc) as acc) = - let kind = Sink.kind sink0 in - let call_site = Sink.call_site sink0 in - let seen_acc' = CallSite.Set.add call_site seen_acc in - let is_recursive sink = CallSite.Set.mem (Sink.call_site sink) seen_acc' in - let matching_sinks = - TaintDomain.trace_fold - (fun acc _ trace -> - match - List.find - ~f:(fun sink -> Sink.Kind.equal kind (Sink.kind sink) && not (is_recursive sink)) - (Sinks.elements (sinks trace)) - with - | Some matching_sink -> - let indexes_match = - not (IntSet.is_empty (IntSet.inter indexes0 (get_footprint_indexes trace))) - in - (matching_sink, indexes_match) :: acc - | None -> - acc ) - (get_summary (CallSite.pname call_site)) - [] - in - (* try to find a sink whose indexes match the current sink *) - try - let matching_sink, _ = List.find_exn ~f:snd matching_sinks in - expand_sink matching_sink (Sink.indexes matching_sink) - (matching_sink :: report_acc, seen_acc') - with Not_found_s _ | Caml.Not_found -> ( - (* didn't find a sink whose indexes match; this can happen when taint flows in via a - global. pick any sink whose kind matches *) - match matching_sinks with - | (matching_sink, _) :: _ -> - expand_sink matching_sink (Sink.indexes matching_sink) - (matching_sink :: report_acc, seen_acc') - | [] -> - acc ) - in - let expanded_sources, _ = - expand_source path_source ([(None, path_source)], CallSite.Set.empty) - in - let expanded_sinks, _ = - expand_sink path_sink sink_indexes ([path_sink], CallSite.Set.empty) - in - let source_trace = - let pp_access_path_opt fmt = function - | None -> - () - | Some access_path -> - let base, _ = AccessPath.Abs.extract access_path in - F.fprintf fmt " with tainted data %a" AccessPath.Abs.pp - ( if Var.is_footprint (fst base) then - (* TODO: resolve footprint identifier to formal name *) - access_path - else access_path ) - in - List.map - ~f:(fun (access_path_opt, path_source) -> - let desc, loc = - let call_site = Source.call_site path_source in - ( Format.asprintf "Return from %a%a" Procname.pp (CallSite.pname call_site) - pp_access_path_opt access_path_opt - , CallSite.loc call_site ) - in - Errlog.make_trace_element 0 loc desc [] ) - expanded_sources - in - let sink_trace = - List.map - ~f:(fun sink -> - let call_site = Sink.call_site sink in - let indexes = Sink.indexes sink in - let indexes_str = - match IntSet.cardinal indexes with - | 0 -> - "" - | 1 -> - " with tainted index " ^ string_of_int (IntSet.choose indexes) - | _ -> - Format.asprintf " with tainted indexes %a" - (PrettyPrintable.pp_collection ~pp_item:Int.pp) - (IntSet.elements indexes) - in - let desc = - Format.asprintf "Call to %a%s" Procname.pp (CallSite.pname call_site) indexes_str - in - Errlog.make_trace_element 0 (CallSite.loc call_site) desc [] ) - expanded_sinks - in - let _, initial_source = List.hd_exn expanded_sources in - let initial_source_caller = Option.map ~f:snd (List.nth expanded_sources 1) in - let final_sink = List.hd_exn expanded_sinks in - let final_sink_caller = List.nth expanded_sinks 1 in - let trace_str = - get_short_trace_string initial_source initial_source_caller final_sink final_sink_caller - in - let ltr = source_trace @ List.rev sink_trace in - Reporting.log_issue proc_desc err_log ~loc:(CallSite.loc cur_site) ~ltr Quandary issue - trace_str - in - List.iter ~f:report_one (TraceDomain.get_reports ~cur_site trace) - - - let add_sink {analysis_data; formal_map} sink actuals access_tree callee_site = - (* add [sink] to the trace associated with the [formal_index]th actual *) - let add_sink_to_actual sink_index access_tree_acc = - match List.nth actuals sink_index with - | Some exp -> ( - match hil_exp_get_node ~abstracted:true exp access_tree_acc formal_map with - | Some (actual_trace, _) -> ( - let sink' = - let indexes = IntSet.singleton sink_index in - TraceDomain.Sink.make ~indexes (TraceDomain.Sink.kind sink) callee_site - in - let actual_trace' = TraceDomain.add_sink sink' actual_trace in - report_trace analysis_data actual_trace' callee_site ; - match HilExp.ignore_cast exp with - | HilExp.AccessExpression actual_ae_raw - when not - (TraceDomain.Sources.Footprint.is_bottom - (TraceDomain.sources actual_trace').footprint ) -> - let actual_ap = - AccessPath.Abs.Abstracted (HilExp.AccessExpression.to_access_path actual_ae_raw) - in - TaintDomain.add_trace actual_ap actual_trace' access_tree_acc - | _ -> - (* no more sources can flow into this sink; no sense in keeping track of it *) - access_tree_acc ) - | _ -> - access_tree_acc ) - | None -> - L.internal_error - "Taint is supposed to flow into sink %a at index %d, but the index is out of bounds" - CallSite.pp callee_site sink_index ; - access_tree_acc - in - IntSet.fold add_sink_to_actual (TraceDomain.Sink.indexes sink) access_tree - - - let apply_summary {analysis_data; formal_map} ret_opt (actuals : HilExp.t list) summary - caller_access_tree callee_site = - let get_caller_ap_node_opt formal_ap access_tree = - let apply_return ret_ap = - match ret_opt with - | Some base_var -> - Some (AccessPath.Abs.with_base base_var ret_ap) - | None -> - (* TODO (T23832636): fail hard here *) - None - in - let project ~formal_ap ~actual_ap = - let projected_ap = AccessPath.append actual_ap (snd (AccessPath.Abs.extract formal_ap)) in - if AccessPath.Abs.is_exact formal_ap then AccessPath.Abs.Exact projected_ap - else AccessPath.Abs.Abstracted projected_ap - in - let base_var, _ = fst (AccessPath.Abs.extract formal_ap) in - match base_var with - | Var.ProgramVar pvar -> - let projected_ap_opt = - if Pvar.is_return pvar then apply_return formal_ap else Some formal_ap - in - let caller_node_opt = - match projected_ap_opt with - | Some projected_ap -> - access_path_get_node projected_ap access_tree formal_map - | None -> - None - in - (projected_ap_opt, Option.value ~default:TaintDomain.empty_node caller_node_opt) - | Var.LogicalVar id when Ident.is_footprint id -> ( - match Option.map (List.nth actuals (Ident.get_stamp id)) ~f:HilExp.ignore_cast with - | Some (HilExp.AccessExpression actual_ae) -> - let projected_ap = - project ~formal_ap ~actual_ap:(HilExp.AccessExpression.to_access_path actual_ae) - in - let caller_node_opt = access_path_get_node projected_ap access_tree formal_map in - (Some projected_ap, Option.value ~default:TaintDomain.empty_node caller_node_opt) - | Some exp -> - let caller_node_opt = hil_exp_get_node exp access_tree formal_map in - (None, Option.value ~default:TaintDomain.empty_node caller_node_opt) - | _ -> - (None, TaintDomain.empty_node) ) - | _ -> - (None, TaintDomain.empty_node) - in - let replace_footprint_sources callee_trace caller_trace access_tree = - let replace_footprint_source acc footprint_access_path (is_mem, _) = - if is_mem then - let _, (caller_ap_trace, _) = - get_caller_ap_node_opt footprint_access_path access_tree - in - TraceDomain.join caller_ap_trace acc - else acc - in - let {TraceDomain.Sources.footprint} = TraceDomain.sources callee_trace in - TraceDomain.Sources.Footprint.fold replace_footprint_source footprint caller_trace - in - let instantiate_and_report callee_trace caller_trace access_tree = - let caller_trace' = replace_footprint_sources callee_trace caller_trace access_tree in - let sink_indexes = TraceDomain.get_footprint_indexes callee_trace in - let appended_trace = TraceDomain.append caller_trace' callee_trace callee_site in - report_trace analysis_data appended_trace callee_site ~sink_indexes ; - appended_trace - in - let add_to_caller_tree access_tree_acc callee_ap callee_trace = - let caller_ap_opt, (caller_trace, caller_tree) = - get_caller_ap_node_opt callee_ap access_tree_acc - in - let trace = instantiate_and_report callee_trace caller_trace access_tree_acc in - let pruned_trace = - if TraceDomain.Sources.Footprint.is_bottom (TraceDomain.sources trace).footprint then - (* empty footprint; nothing else can flow into these sinks. so don't track them *) - TraceDomain.update_sinks trace TraceDomain.Sinks.empty - else trace - in - match caller_ap_opt with - | Some caller_ap -> - TaintDomain.add_node caller_ap (pruned_trace, caller_tree) access_tree_acc - | None -> - access_tree_acc - in - TaintDomain.trace_fold add_to_caller_tree summary caller_access_tree - - - (* not all sinks are function calls; we might want to treat an array or field access as a - sink too. do this by pretending an access is a call to a dummy function and using the - existing machinery for adding function call sinks *) - let add_sinks_for_access_path ({analysis_data= {tenv}} as analysis_data) access_expr loc astate - = - let rec add_sinks_for_access astate_acc (access_expr : HilExp.AccessExpression.t) = - match access_expr with - | Base _ -> - astate_acc - | FieldOffset (ae, _) | ArrayOffset (ae, _, None) | AddressOf ae | Dereference ae -> - add_sinks_for_access astate_acc ae - | ArrayOffset (ae, _, Some index) -> - let dummy_call_site = CallSite.make BuiltinDecl.__array_access loc in - let dummy_actuals = - List.map - ~f:(fun index_ae -> HilExp.AccessExpression index_ae) - (HilExp.get_access_exprs index) - in - let sinks = TraceDomain.Sink.get dummy_call_site dummy_actuals CallFlags.default tenv in - let astate_acc_result = - List.fold sinks ~init:astate_acc ~f:(fun astate sink -> - add_sink analysis_data sink dummy_actuals astate dummy_call_site ) - in - add_sinks_for_access astate_acc_result ae - in - add_sinks_for_access astate access_expr - - - let add_sources_for_access_path {analysis_data= {proc_desc; tenv}} access_expr loc astate = - let var, _ = HilExp.AccessExpression.get_base access_expr in - if Var.is_global var then - let dummy_call_site = CallSite.make BuiltinDecl.__global_access loc in - let sources = - let caller_pname = Procdesc.get_proc_name proc_desc in - TraceDomain.Source.get ~caller_pname dummy_call_site - [HilExp.AccessExpression access_expr] - tenv - in - List.fold sources ~init:astate ~f:(fun astate {TraceDomain.Source.source} -> - let access_path = - AccessPath.Abs.Exact (HilExp.AccessExpression.to_access_path access_expr) - in - let trace, subtree = - Option.value ~default:TaintDomain.empty_node (TaintDomain.get_node access_path astate) - in - TaintDomain.add_node access_path (TraceDomain.add_source source trace, subtree) astate ) - else astate - - - let rec add_sources_sinks_for_exp proc_data exp loc astate = - match exp with - | HilExp.Cast (_, e) -> - add_sources_sinks_for_exp proc_data e loc astate - | HilExp.AccessExpression access_expr -> - add_sinks_for_access_path proc_data access_expr loc astate - |> add_sources_for_access_path proc_data access_expr loc - | _ -> - astate - - - let exec_write formal_map lhs_access_expr rhs_exp astate = - let rhs_node = - Option.value (hil_exp_get_node rhs_exp astate formal_map) ~default:TaintDomain.empty_node - in - let lhs_access_path = HilExp.AccessExpression.to_access_path lhs_access_expr in - TaintDomain.add_node (AccessPath.Abs.Exact lhs_access_path) rhs_node astate - - - let analyze_call - ({analysis_data= {proc_desc; tenv; analyze_dependency}; formal_map} as analysis_data) - ~ret_ap ~callee_pname ~actuals ~call_flags ~callee_loc astate = - let astate = - List.fold - ~f:(fun acc exp -> add_sources_sinks_for_exp analysis_data exp callee_loc acc) - actuals ~init:astate - in - let handle_model callee_pname access_tree model = - let is_variadic = - match callee_pname with - | Procname.Java pname -> - Procname.Java.is_vararg pname - | _ -> - false - in - let should_taint_typ typ = is_variadic || TaintSpecification.is_taintable_type typ in - let exp_join_traces trace_acc exp = - match hil_exp_get_node ~abstracted:true exp access_tree formal_map with - | Some (trace, _) -> - TraceDomain.join trace trace_acc - | None -> - trace_acc - in - let propagate_to_access_path access_path actuals access_tree = - let initial_trace = access_path_get_trace access_path access_tree formal_map in - let trace_with_propagation = List.fold ~f:exp_join_traces ~init:initial_trace actuals in - let sources = TraceDomain.sources trace_with_propagation in - let filtered_footprint = - TraceDomain.Sources.Footprint.fold - (fun acc access_path (is_mem, _) -> - if - is_mem - && Option.exists - (AccessPath.get_typ (AccessPath.Abs.extract access_path) tenv) - ~f:should_taint_typ - then TraceDomain.Sources.Footprint.add_trace access_path true acc - else acc ) - sources.footprint TraceDomain.Sources.Footprint.bottom - in - let filtered_sources = {sources with footprint= filtered_footprint} in - if TraceDomain.Sources.is_empty filtered_sources then access_tree - else - let trace' = TraceDomain.update_sources trace_with_propagation filtered_sources in - let pruned_trace = - if TraceDomain.Sources.Footprint.is_bottom filtered_footprint then - (* empty footprint; nothing else can flow into these sinks. so don't track them *) - TraceDomain.update_sinks trace' TraceDomain.Sinks.empty - else trace' - in - TaintDomain.add_trace access_path pruned_trace access_tree - in - let handle_model_ astate_acc propagation = - match (propagation, actuals) with - | _, [] -> - astate_acc - | TaintSpec.Propagate_to_return, actuals -> - propagate_to_access_path (AccessPath.Abs.Abstracted (ret_ap, [])) actuals astate_acc - | ( TaintSpec.Propagate_to_receiver - , HilExp.AccessExpression receiver_ae :: (_ :: _ as other_actuals) ) -> - propagate_to_access_path - (AccessPath.Abs.Abstracted (HilExp.AccessExpression.to_access_path receiver_ae)) - other_actuals astate_acc - | TaintSpec.Propagate_to_actual actual_index, _ -> ( - match Option.map (List.nth actuals actual_index) ~f:HilExp.ignore_cast with - | Some (HilExp.AccessExpression actual_ae) -> - propagate_to_access_path - (AccessPath.Abs.Abstracted (HilExp.AccessExpression.to_access_path actual_ae)) - actuals astate_acc - | _ -> - astate_acc ) - | _ -> - astate_acc - in - List.fold ~f:handle_model_ ~init:access_tree model - in - let handle_unknown_call callee_pname access_tree = - match Procname.get_method callee_pname with - | "operator=" when not (Procname.is_java callee_pname) -> ( - (* treat unknown calls to C++ operator= as assignment *) - match List.map actuals ~f:HilExp.ignore_cast with - | [AccessExpression lhs_access_expr; rhs_exp] -> - exec_write formal_map lhs_access_expr rhs_exp access_tree - | [AccessExpression lhs_access_expr; rhs_exp; HilExp.AccessExpression access_expr] -> ( - let dummy_ret_access_expr = access_expr in - match dummy_ret_access_expr with - | HilExp.AccessExpression.Base (Var.ProgramVar pvar, _) when Pvar.is_frontend_tmp pvar - -> - (* the frontend translates operator=(x, y) as operator=(x, y, dummy_ret) when - operator= returns a value type *) - exec_write formal_map lhs_access_expr rhs_exp access_tree - |> exec_write formal_map dummy_ret_access_expr rhs_exp - | _ -> - L.internal_error "Unexpected call to operator= at %a" Location.pp callee_loc ; - access_tree ) - | _ -> - L.internal_error "Unexpected call to operator= at %a" Location.pp callee_loc ; - access_tree ) - | _ -> - let model = - TaintSpecification.handle_unknown_call callee_pname (snd ret_ap) actuals tenv - in - handle_model callee_pname access_tree model - in - let dummy_ret_opt = - match ret_ap with - | _, {Typ.desc= Tvoid} when not (Procname.is_java callee_pname) -> ( - (* the C++ frontend handles returns of non-pointers by adding a dummy - pass-by-reference variable as the last actual, then returning the value by - assigning to it. understand this pattern by pretending it's the return value *) - match List.last actuals with - | Some (HilExp.AccessExpression access_expr) -> ( - match HilExp.AccessExpression.to_access_path access_expr with - | ((Var.ProgramVar pvar, _) as ret_base), [] when Pvar.is_frontend_tmp pvar -> - Some ret_base - | _ -> - None ) - | _ -> - None ) - | _ -> - Some ret_ap - in - let call_site = CallSite.make callee_pname callee_loc in - let astate_with_sink = - if List.is_empty actuals then astate - else - let sinks = TraceDomain.Sink.get call_site actuals call_flags tenv in - List.fold sinks ~init:astate ~f:(fun astate sink -> - add_sink analysis_data sink actuals astate call_site ) - in - let astate_with_direct_sources = - let sources = - let caller_pname = Procdesc.get_proc_name proc_desc in - TraceDomain.Source.get ~caller_pname call_site actuals tenv - in - List.fold sources ~init:astate_with_sink - ~f:(fun astate {TraceDomain.Source.source; index} -> - match index with - | None -> - Option.value_map dummy_ret_opt ~default:astate ~f:(fun ret_base -> - add_return_source source ret_base astate ) - | Some index -> - add_actual_source source index actuals astate_with_sink formal_map ) - in - let astate_with_summary = - match analyze_dependency callee_pname with - | Error _ -> - handle_unknown_call callee_pname astate_with_direct_sources - | Ok summary -> ( - let ret_typ = snd ret_ap in - let access_tree = TaintSpecification.of_summary_access_tree summary in - match TaintSpecification.get_model callee_pname ret_typ actuals tenv access_tree with - | Some model -> - handle_model callee_pname astate_with_direct_sources model - | None -> - apply_summary analysis_data dummy_ret_opt actuals access_tree - astate_with_direct_sources call_site ) - in - let astate_with_sanitizer = - match dummy_ret_opt with - | None -> - astate_with_summary - | Some ret_base -> ( - match TraceDomain.Sanitizer.get callee_pname tenv with - | Some sanitizer -> - let ret_ap = AccessPath.Abs.Exact (ret_base, []) in - let ret_trace = access_path_get_trace ret_ap astate_with_summary formal_map in - let ret_trace' = TraceDomain.add_sanitizer sanitizer ret_trace in - TaintDomain.add_trace ret_ap ret_trace' astate_with_summary - | None -> - astate_with_summary ) - in - astate_with_sanitizer - - - let exec_instr (astate : Domain.t) ({analysis_data= {proc_desc}; formal_map} as analysis_data) _ - _ (instr : HilInstr.t) = - match instr with - | Assign (Base (Var.ProgramVar pvar, _), HilExp.Exception _, _) when Pvar.is_return pvar -> - (* the Java frontend translates `throw Exception` as `return Exception`, which is a bit - wonky. this translation causes problems for us in computing a summary when an - exception is "returned" from a void function. skip code like this for now, fix via - t14159157 later *) - astate - | Assign (Base (Var.ProgramVar pvar, _), rhs_exp, _) - when Pvar.is_return pvar && HilExp.is_null_literal rhs_exp - && Typ.equal_desc Tvoid (Procdesc.get_ret_type proc_desc).desc -> - (* similar to the case above; the Java frontend translates "return no exception" as - `return null` in a void function *) - astate - | Assign (lhs_access_expr, rhs_exp, loc) -> - add_sources_sinks_for_exp analysis_data rhs_exp loc astate - |> add_sinks_for_access_path analysis_data lhs_access_expr loc - |> exec_write formal_map lhs_access_expr rhs_exp - | Assume (assume_exp, _, _, loc) -> - add_sources_sinks_for_exp analysis_data assume_exp loc astate - | Call (ret_ap, Direct callee_pname, actuals, call_flags, callee_loc) -> - analyze_call analysis_data ~ret_ap ~callee_pname ~actuals ~call_flags ~callee_loc astate - | _ -> - astate - - - let pp_session_name = - let name = F.sprintf "quandary(%s)" TaintSpecification.name in - fun (_node : CFG.Node.t) fmt -> F.pp_print_string fmt name - end - - module HilConfig : LowerHil.HilConfig = struct - (* we want this so we can treat array accesses as sinks *) - let include_array_indexes = true - end - - module Analyzer = - LowerHil.MakeAbstractInterpreterWithConfig (AbstractInterpreter.MakeRPO) (HilConfig) - (TransferFunctions (ProcCfg.Exceptional)) - - (* sanity checks for summaries. should only be used in developer mode *) - let check_invariants access_tree = - let open TraceDomain in - TaintDomain.iter - (fun access_path (trace, _) -> - let sources = sources trace in - let footprint_sources = sources.footprint in - let passthroughs = passthroughs trace in - let sinks = sinks trace in - (* invariant 1: sinks with no footprint sources are dead and should be forgotten *) - if Sources.Footprint.is_bottom footprint_sources && not (Sinks.is_empty sinks) then - Logging.die InternalError - "Trace %a associated with %a tracks sinks even though no more sources can flow into \ - them" - Sinks.pp sinks AccessPath.Abs.pp access_path ; - (* invariant 2: we should never have sinks without sources *) - if Sources.is_empty sources && not (Sinks.is_empty sinks) then - Logging.die InternalError "We have sinks %a associated with %a, but no sources" Sinks.pp - sinks AccessPath.Abs.pp access_path ; - (* invariant 3: we should never have passthroughs without sources *) - if Sources.is_empty sources && not (Passthroughs.is_empty passthroughs) then - Logging.die InternalError "We have passthroughs %a associated with %a, but no sources" - Passthroughs.pp passthroughs AccessPath.Abs.pp access_path ; - (* invariant 4: we should never map an access path to a trace consisting only of its - corresponding footprint source. a trace like this is a waste of space, since we can - lazily create it if/when someone actually tries to read the access path instead *) - (* TODO: tmp to focus on invariant 1 *) - if - false - && AccessPath.Abs.is_exact access_path - && Sinks.is_empty sinks - && Sources.Footprint.mem access_path footprint_sources - && Sources.Footprint.exists - (fun footprint_access_path (is_mem, _) -> - is_mem && AccessPath.Abs.equal access_path footprint_access_path ) - footprint_sources - then - Logging.die InternalError - "The trace associated with %a consists only of its footprint source: %a" - AccessPath.Abs.pp access_path pp trace ) - access_tree - - - let make_summary {analysis_data= {proc_desc}; formal_map} access_tree = - let is_java = Procname.is_java (Procdesc.get_proc_name proc_desc) in - (* if a trace has footprint sources, attach them to the appropriate footprint var *) - let access_tree' = - TaintDomain.fold - (fun access_tree_acc _ ((trace, _) as node) -> - if TraceDomain.Sinks.is_empty (TraceDomain.sinks trace) then - (* if this trace has no sinks, we don't need to attach it to anything *) - access_tree_acc - else - TraceDomain.Sources.Footprint.fold - (fun acc footprint_access_path (is_mem, _) -> - if is_mem then - let node' = - match TaintDomain.get_node footprint_access_path acc with - | Some n -> - TaintDomain.node_join node n - | None -> - node - in - TaintDomain.add_node footprint_access_path node' acc - else acc ) - (TraceDomain.sources trace).TraceDomain.Sources.footprint access_tree_acc ) - access_tree access_tree - in - (* should only be used on nodes associated with a footprint base *) - let is_empty_node (trace, tree) = - (* In C++, we can reassign the value pointed to by a pointer type formal, and we can assign - to a value type passed by reference. these mechanisms can be used to associate a source - directly with a formal. In Java this can't happen, so we only care if the formal flows to - a sink *) - ( if is_java then TraceDomain.Sinks.is_empty (TraceDomain.sinks trace) - else TraceDomain.is_bottom trace ) - && - match tree with - | TaintDomain.Subtree subtree -> - TaintDomain.AccessMap.is_empty subtree - | TaintDomain.Star -> - true - in - (* replace formal names with footprint vars for their indices. For example, for `foo(o)`, we'll - replace `o` with FP(1) *) - let with_footprint_vars = - AccessPath.BaseMap.fold - (fun base ((trace, subtree) as node) acc -> - if Var.is_global (fst base) || Var.is_return (fst base) then - AccessPath.BaseMap.add base node acc - else if Var.is_footprint (fst base) then - if is_empty_node node then acc - else - let node' = - if TraceDomain.Sinks.is_empty (TraceDomain.sinks trace) then - (TraceDomain.bottom, subtree) - else node - in - AccessPath.BaseMap.add base node' acc - else - match FormalMap.get_formal_index base formal_map with - | Some formal_index -> - let base' = (Var.of_formal_index formal_index, snd base) in - let joined_node = - try TaintDomain.node_join (AccessPath.BaseMap.find base' acc) node - with Caml.Not_found -> node - in - if is_empty_node joined_node then acc - else AccessPath.BaseMap.add base' joined_node acc - | None -> - (* base is a local var *) - acc ) - access_tree' TaintDomain.bottom - in - if Config.developer_mode then check_invariants with_footprint_vars ; - TaintSpecification.to_summary_access_tree with_footprint_vars - - - let checker ({InterproceduralAnalysis.proc_desc; tenv} as analysis_data) = - let pname = Procdesc.get_proc_name proc_desc in - (* bind parameters to a trace with a tainted source (if applicable) *) - let make_initial pdesc = - List.fold - ~f:(fun acc (name, typ, taint_opt) -> - match taint_opt with - | Some source -> - let base_ap = - AccessPath.Abs.Abstracted (AccessPath.of_pvar (Pvar.mk name pname) typ) - in - TaintDomain.add_trace base_ap (TraceDomain.of_source source) acc - | None -> - acc ) - ~init:TaintDomain.bottom - (TraceDomain.Source.get_tainted_formals pdesc tenv) - in - let initial = make_initial proc_desc in - let formal_map = FormalMap.make (Procdesc.get_attributes proc_desc) in - let proc_data = {analysis_data; formal_map} in - match Analyzer.compute_post proc_data ~initial proc_desc with - | Some access_tree -> - Some (make_summary proc_data access_tree) - | None -> - if not (List.is_empty (Procdesc.Node.get_succs (Procdesc.get_start_node proc_desc))) then - L.internal_error "Couldn't compute post for %a. Broken CFG suspected" Procname.pp pname ; - None -end diff --git a/infer/src/quandary/TaintSpec.ml b/infer/src/quandary/TaintSpec.ml deleted file mode 100644 index 00cc1c443ed..00000000000 --- a/infer/src/quandary/TaintSpec.ml +++ /dev/null @@ -1,42 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd - -(** combination of a trace with functions for handling unknown code and converting to and from - summaries *) - -type action = - | Propagate_to_actual of int - (** Propagate taint from all actuals to the actual with the given index *) - | Propagate_to_receiver - (** Propagate taint from all non-receiver actuals to the receiver actual *) - | Propagate_to_return (** Propagate taint from all actuals to the return value *) - -module type S = sig - module Trace : TaintTrace.S - - module AccessTree : module type of AccessTree.Make (Trace) (AccessTree.DefaultConfig) - - val handle_unknown_call : Procname.t -> Typ.t -> HilExp.t list -> Tenv.t -> action list - (** return a summary for handling an unknown call at the given site with the given return type and - actuals *) - - val get_model : - Procname.t -> Typ.t -> HilExp.t list -> Tenv.t -> AccessTree.t -> action list option - (** returns a model that should be used for the given (procname, return type, actuals, summary) - instead of using the summary for the procname *) - - val is_taintable_type : Typ.t -> bool - (** return true if the given typ can be tainted *) - - val to_summary_access_tree : AccessTree.t -> QuandarySummary.AccessTree.t - - val of_summary_access_tree : QuandarySummary.AccessTree.t -> AccessTree.t - - val name : string -end diff --git a/infer/src/quandary/dune b/infer/src/quandary/dune deleted file mode 100644 index 1f29ae0ff2e..00000000000 --- a/infer/src/quandary/dune +++ /dev/null @@ -1,27 +0,0 @@ -; Copyright (c) Facebook, Inc. and its affiliates. -; -; This source code is licensed under the MIT license found in the -; LICENSE file in the root directory of this source tree. - -(library - (name Quandary) - (public_name infer.Quandary) - (flags - (:standard - -open - Core - -open - IR - -open - IStdlib - -open - IStd - -open - ATDGenerated - -open - IBase - -open - Absint)) - (libraries core ppx_show.runtime IStdlib ATDGenerated IBase IR Absint) - (preprocess - (pps ppx_compare ppx_show))) diff --git a/infer/src/unit/TaintTests.ml b/infer/src/unit/TaintTests.ml deleted file mode 100644 index 53ad91ac876..00000000000 --- a/infer/src/unit/TaintTests.ml +++ /dev/null @@ -1,164 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd -module F = Format - -module MockTrace = TaintTrace.Make (struct - module MockTraceElem = struct - include CallSite - - let matches ~caller ~callee = equal caller callee - end - - module Source = Source.Make (struct - include MockTraceElem - - let get ~caller_pname:_ pname _ _ = - if String.is_prefix ~prefix:"SOURCE" (Procname.to_string pname) then - [(CallSite.make pname Location.dummy, None)] - else [] - - - let get_tainted_formals _ _ = [] - end) - - module Sink = Sink.Make (struct - include MockTraceElem - - let get pname _ _ _ = - if String.is_prefix ~prefix:"SINK" (Procname.to_string pname) then - [(CallSite.make pname Location.dummy, IntSet.singleton 0)] - else [] - end) - - module Sanitizer = Sanitizer.Dummy - - let get_report _ _ _ = None -end) - -module MockTaintAnalysis = TaintAnalysis.Make (struct - module Trace = MockTrace - module AccessTree = AccessTree.Make (Trace) (AccessTree.DefaultConfig) - - let of_summary_access_tree _ = assert false - - let to_summary_access_tree _ = assert false - - let handle_unknown_call _ _ _ _ = [] - - let is_taintable_type _ = true - - let get_model _ _ _ _ _ = None - - let name = "" -end) - -module TestInterpreter = - AnalyzerTester.Make - (LowerHil.Make (MockTaintAnalysis.TransferFunctions (ProcCfg.Normal)) (LowerHil.DefaultConfig)) - -let tests = - let open OUnit2 in - let open AnalyzerTester.StructuredSil in - (* less verbose form of pretty-printing to make writing tests easy *) - let pp_sparse fmt astate = - let pp_call_site fmt call_site = Procname.pp fmt (CallSite.pname call_site) in - let pp_sources fmt sources = - if MockTrace.Sources.is_empty sources then F.pp_print_char fmt '?' - else - MockTrace.Sources.Known.iter - (fun source -> pp_call_site fmt (MockTrace.Source.call_site source)) - sources.MockTrace.Sources.known - in - let pp_sinks fmt sinks = - if MockTrace.Sinks.is_empty sinks then F.pp_print_char fmt '?' - else MockTrace.Sinks.iter (fun sink -> pp_call_site fmt (MockTrace.Sink.call_site sink)) sinks - in - (* just print source -> sink, no line nums or passthroughs *) - let pp_trace fmt trace = - F.fprintf fmt "(%a -> %a)" pp_sources (MockTrace.sources trace) pp_sinks - (MockTrace.sinks trace) - in - let pp_item fmt (ap, trace) = F.fprintf fmt "%a => %a" AccessPath.Abs.pp ap pp_trace trace in - (* flatten access tree into list of access paths with associated traces *) - let trace_assocs = - MockTaintAnalysis.TaintDomain.trace_fold - (fun acc ap t -> if not (MockTrace.is_bottom t) then (ap, t) :: acc else acc) - (fst astate) [] - in - PrettyPrintable.pp_collection ~pp_item fmt (List.rev trace_assocs) - in - let assign_to_source ret_str = - let procname = Procname.from_string_c_fun "SOURCE" in - make_call ~procname ~return:(ident_of_str ret_str, dummy_typ) [] - in - let assign_to_non_source ret_str = - let procname = Procname.from_string_c_fun "NON-SOURCE" in - make_call ~procname ~return:(ident_of_str ret_str, dummy_typ) [] - in - let call_sink_with_exp exp = - let procname = Procname.from_string_c_fun "SINK" in - make_call ~procname [(exp, dummy_typ)] - in - let call_sink actual_str = call_sink_with_exp (Exp.Var (ident_of_str actual_str)) in - let assign_id_to_field root_str fld_str rhs_id_str = - let rhs_exp = Exp.Var (ident_of_str rhs_id_str) in - make_store ~rhs_typ:StdTyp.void (Exp.Var (ident_of_str root_str)) fld_str ~rhs_exp - in - let read_field_to_id lhs_id_str root_str fld_str = - make_load_fld ~rhs_typ:StdTyp.void lhs_id_str fld_str (Exp.Var (ident_of_str root_str)) - in - let assert_empty = invariant "{ }" in - let test_list = - [ ("source recorded", [assign_to_source "ret_id"; invariant "{ ret_id$0* => (SOURCE -> ?) }"]) - ; ("non-source not recorded", [assign_to_non_source "ret_id"; assert_empty]) - ; ( "source flows to var" - , [ assign_to_source "ret_id" - ; var_assign_id "var" "ret_id" - ; invariant "{ ret_id$0* => (SOURCE -> ?), var* => (SOURCE -> ?) }" ] ) - ; ( "source flows to field" - , [ assign_to_source "ret_id" - ; assign_id_to_field "base_id" "f" "ret_id" - ; invariant "{ base_id$0.f* => (SOURCE -> ?), ret_id$0* => (SOURCE -> ?) }" ] ) - ; ( "source flows to field then var" - , [ assign_to_source "ret_id" - ; assign_id_to_field "base_id" "f" "ret_id" - ; read_field_to_id "read_id" "base_id" "f" - ; var_assign_id "var" "read_id" - ; invariant - "{ base_id$0.f* => (SOURCE -> ?),\n\ - \ ret_id$0* => (SOURCE -> ?),\n\ - \ var* => (SOURCE -> ?) }" ] ) - ; ( "source flows to var then cleared" - , [ assign_to_source "ret_id" - ; var_assign_id "var" "ret_id" - ; invariant "{ ret_id$0* => (SOURCE -> ?), var* => (SOURCE -> ?) }" - ; assign_to_non_source "non_source_id" - ; var_assign_id "var" "non_source_id" - ; invariant "{ ret_id$0* => (SOURCE -> ?) }" ] ) - ; ( "source flows to field then cleared" - , [ assign_to_source "ret_id" - ; assign_id_to_field "base_id" "f" "ret_id" - ; invariant "{ base_id$0.f* => (SOURCE -> ?), ret_id$0* => (SOURCE -> ?) }" - ; assign_to_non_source "non_source_id" - ; assign_id_to_field "base_id" "f" "non_source_id" - ; invariant "{ ret_id$0* => (SOURCE -> ?) }" ] ) - ; ( "sink without source not tracked" - , [assign_to_non_source "ret_id"; call_sink "ret_id"; assert_empty] ) ] - |> TestInterpreter.create_tests ~pp_opt:pp_sparse - (fun summary -> - let proc_desc = Procdesc.load_exn summary.proc_name in - { analysis_data= - CallbackOfChecker.mk_interprocedural_field_t Payloads.Fields.quandary - {proc_desc; exe_env= Exe_env.mk (); summary} - ~tenv:(Tenv.create ()) () - |> fst - ; formal_map= FormalMap.empty } ) - ~initial:(MockTaintAnalysis.Domain.bottom, Bindings.empty) - in - "taint_test_suite" >::: test_list diff --git a/infer/src/unit/TraceTests.ml b/infer/src/unit/TraceTests.ml deleted file mode 100644 index 9c0d8838fc4..00000000000 --- a/infer/src/unit/TraceTests.ml +++ /dev/null @@ -1,114 +0,0 @@ -(* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -open! IStd - -module MockTraceElem = struct - type t = Kind1 | Kind2 [@@deriving compare, equal, show {with_path= false}] - - let matches ~caller ~callee = Int.equal 0 (compare caller callee) - - let call_site _ = CallSite.dummy - - let kind t = t - - let make ?indexes:_ kind _ = kind - - module Kind = struct - type nonrec t = t [@@deriving compare, equal] - - let matches = matches - - let pp = pp - end - - module Set = PrettyPrintable.MakePPSet (struct - type nonrec t = t [@@deriving compare] - - let pp = pp - end) - - let with_callsite t _ = t - - let with_indexes t _ = t -end - -module MockSource = struct - include Source.Make (struct - include MockTraceElem - - let get ~caller_pname:_ _ _ = assert false - - let get_tainted_formals _ = assert false - end) -end - -module MockSink = struct - include MockTraceElem - - let get _ = assert false - - let indexes _ = IntSet.empty -end - -module MockTrace = TaintTrace.Make (struct - module Source = MockSource - module Sink = MockSink - module Sanitizer = Sanitizer.Dummy - - let get_report source sink _ = - if MockTraceElem.equal (Source.kind source) (Sink.kind sink) then - Some IssueType.quandary_taint_error - else None -end) - -let trace_equal t1 t2 = MockTrace.leq ~lhs:t1 ~rhs:t2 && MockTrace.leq ~lhs:t2 ~rhs:t1 - -let source_equal s source = MockSource.equal s source - -let tests = - let source1 = MockSource.make MockTraceElem.Kind1 CallSite.dummy in - let source2 = MockSource.make MockTraceElem.Kind2 CallSite.dummy in - let sink1 = MockSink.make MockTraceElem.Kind1 CallSite.dummy in - let sink2 = MockSink.make MockTraceElem.Kind2 CallSite.dummy in - let open OUnit2 in - let get_reports = - let get_reports_ _ = - let trace = - MockTrace.of_source source1 |> MockTrace.add_source source2 |> MockTrace.add_sink sink1 - |> MockTrace.add_sink sink2 - in - let reports = MockTrace.get_reports trace in - assert_equal (List.length reports) 2 ; - assert_bool "Reports should contain source1 -> sink1" - (List.exists - ~f:(fun {MockTrace.path_source; path_sink} -> - source_equal path_source source1 && MockSink.equal path_sink sink1 ) - reports ) ; - assert_bool "Reports should contain source2 -> sink2" - (List.exists - ~f:(fun {MockTrace.path_source; path_sink} -> - source_equal path_source source2 && MockSink.equal path_sink sink2 ) - reports ) - in - "get_reports" >:: get_reports_ - in - let append = - let append_ _ = - let call_site = CallSite.dummy in - let footprint_ap = - AccessPath.Abs.Exact (AccessPath.of_id (Ident.create_none ()) StdTyp.void) - in - let source_trace = MockTrace.of_source source1 in - let footprint_trace = MockTrace.of_footprint footprint_ap |> MockTrace.add_sink sink1 in - let expected_trace = MockTrace.of_source source1 |> MockTrace.add_sink sink1 in - assert_bool "Appended trace should contain source and sink" - (trace_equal (MockTrace.append source_trace footprint_trace call_site) expected_trace) - in - "append" >:: append_ - in - "trace_domain_suite" >::: [get_reports; append] diff --git a/infer/src/unit/analyzerTester.ml b/infer/src/unit/analyzerTester.ml index d13382807bc..eaa9b169f45 100644 --- a/infer/src/unit/analyzerTester.ml +++ b/infer/src/unit/analyzerTester.ml @@ -100,18 +100,6 @@ module StructuredSil = struct Cmd (Sil.Call (ret_id_typ, call_exp, args, dummy_loc, CallFlags.default)) - let make_store ~rhs_typ root_exp fld_str ~rhs_exp = - let fld = AccessPathTestUtils.make_fieldname fld_str in - let lhs_exp = Exp.Lfield (root_exp, fld, rhs_typ) in - make_set ~rhs_typ ~lhs_exp ~rhs_exp - - - let make_load_fld ~rhs_typ lhs_str fld_str root_exp = - let fld = AccessPathTestUtils.make_fieldname fld_str in - let rhs_exp = Exp.Lfield (root_exp, fld, rhs_typ) in - make_load ~rhs_typ (ident_of_str lhs_str) rhs_exp - - let id_assign_exp ?(rhs_typ = dummy_typ) lhs rhs_exp = let lhs_id = ident_of_str lhs in make_load ~rhs_typ lhs_id rhs_exp @@ -144,12 +132,6 @@ module StructuredSil = struct var_assign_exp ~rhs_typ lhs rhs_exp - let var_assign_id ?(rhs_typ = dummy_typ) lhs rhs = - let lhs_exp = var_of_str lhs in - let rhs_exp = Exp.Var (ident_of_str rhs) in - make_set ~rhs_typ ~lhs_exp ~rhs_exp - - (* x = &y *) let var_assign_addrof_var ?(rhs_typ = dummy_typ) lhs rhs = let lhs_exp = var_of_str lhs in diff --git a/infer/src/unit/dune.in b/infer/src/unit/dune.in index 5d5cf8238eb..ac643452cd0 100644 --- a/infer/src/unit/dune.in +++ b/infer/src/unit/dune.in @@ -15,9 +15,9 @@ let library = (flags (:standard -open Core -open IR -open IStdlib -open IStd -open ATDGenerated -open IBase -open Absint -open Backend -open CStubs -open ClangFrontend %s - -open Checkers -open Quandary -open TestDeterminators -open Integration)) + -open Checkers -open TestDeterminators -open Integration)) (libraries oUnit core ppx_show.runtime IStdlib ATDGenerated IBase IR Absint Backend CStubs ClangFrontend - Checkers Quandary TestDeterminators Integration) + Checkers TestDeterminators Integration) (preprocess (pps ppx_compare ppx_hash ppx_show)) )|} (if clang then "-open ClangFrontend" else "-open ClangFrontendStubs") diff --git a/infer/tests/codetoanalyze/cpp/quandary/.inferconfig b/infer/tests/codetoanalyze/cpp/quandary/.inferconfig deleted file mode 100644 index d69bff77904..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/.inferconfig +++ /dev/null @@ -1,111 +0,0 @@ -{ - "force-delete-results-dir": true, - "quandary-sources": [ - { - "procedure": "__infer_taint_source", - "kind": "Other" - }, - { - "procedure": "basics::Obj::method_source", - "kind": "Other" - }, - { - "procedure": "basics::Obj::static_source", - "kind": "Other" - }, - { - "procedure": "basics::template_source", - "kind": "Other" - }, - { - "procedure": "basics::Obj::string_source", - "kind": "Other" - }, - { - "procedure": "basics::Obj::taint_arg_source", - "kind": "Other", - "index": "0" - }, - { - "procedure": "allocs::allocation_source", - "kind": "EnvironmentVariable" - } - ], - "quandary-sinks": [ - { - "procedure": "__infer_taint_sink", - "kind": "Other", - "index": "0" - }, - { - "procedure": "__infer_sql_sink", - "kind": "SQLInjection", - "index": "all" - }, - { - "procedure": "__infer_sql_read_sink", - "kind": "SQLRead", - "index": "all" - }, - { - "procedure": "__infer_sql_write_sink", - "kind": "SQLWrite", - "index": "all" - }, - { - "procedure": "__infer_url_sink", - "kind": "URL", - "index": "all" - }, - { - "procedure": "basics::Obj::method_sink", - "kind": "Other", - "index": "1" - }, - { - "procedure": "basics::Obj::static_sink", - "kind": "Other", - "index": "0" - }, - { - "procedure": "basics::template_sink", - "kind": "Other", - "index": "0" - }, - { - "procedure": "basics::Obj::string_sink", - "kind": "Other", - "index": "1" - } - ], - "quandary-sanitizers": [ - { - "procedure": "__infer_all_sanitizer", - "kind": "All" - }, - { - "procedure": "__infer_shell_sanitizer", - "kind": "EscapeShell" - }, - { - "procedure": "__infer_sql_sanitizer", - "kind": "EscapeSQL" - }, - { - "procedure": "__infer_url_sanitizer", - "kind": "EscapeURL" - }, - { - "procedure": "basics::Obj::sanitizer1" - }, - { - "procedure": "basics::Obj::sanitizer2" - } - ], - "quandary-endpoints": [ - "basics::Obj::endpoint", - "endpoints::Service1::user_controlled_endpoint_to_sql_bad", - "endpoints::Service1::user_controlled_endpoint_to_shell_bad", - "execs::Obj::endpoint" - ] -} diff --git a/infer/tests/codetoanalyze/cpp/quandary/Makefile b/infer/tests/codetoanalyze/cpp/quandary/Makefile deleted file mode 100644 index d13464c7164..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (c) Facebook, Inc. and its affiliates. -# -# This source code is licensed under the MIT license found in the -# LICENSE file in the root directory of this source tree. - -TESTS_DIR = ../../.. - -# see explanations in cpp/biabduction/Makefile for the custom isystem -CLANG_OPTIONS = -x c++ -std=c++11 -nostdinc++ -isystem$(ROOT_DIR) -isystem$(CLANG_INCLUDES)/c++/v1/ -c -INFER_OPTIONS = --quandary-only --quandary-show-passthroughs --debug-exceptions \ - --project-root $(TESTS_DIR) \ - -INFERPRINT_OPTIONS = --issues-tests - -SOURCES = $(wildcard *.cpp) - -include $(TESTS_DIR)/clang.make diff --git a/infer/tests/codetoanalyze/cpp/quandary/allocs.cpp b/infer/tests/codetoanalyze/cpp/quandary/allocs.cpp deleted file mode 100644 index 5596e9c3177..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/allocs.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include - -namespace allocs { - -extern int* allocation_source(); - -void untrusted_malloc_bad() { malloc(*allocation_source()); } - -void untrusted_calloc_bad1() { calloc(*allocation_source(), sizeof(int)); } - -void untrusted_calloc_bad2() { calloc(5, *allocation_source()); } - -void untrusted_reaalloc_bad1() { realloc(allocation_source(), sizeof(int)); } - -void untrusted_reaalloc_bad2(int* i) { realloc(i, *allocation_source()); } - -void untrusted_brk_bad() { brk((void*)allocation_source()); } - -void untrusted_sbrk_bad() { sbrk(*allocation_source()); } -} // namespace allocs diff --git a/infer/tests/codetoanalyze/cpp/quandary/arrays.cpp b/infer/tests/codetoanalyze/cpp/quandary/arrays.cpp deleted file mode 100644 index 1d6508f2046..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/arrays.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include - -extern int __infer_taint_source(); -extern void skip(int i, int j); - -// mocking gflags-generated field -extern int FLAGS_size; - -namespace arrays { - -void array_sink1_bad(int arr[]) { - int source = __infer_taint_source(); - arr[source] = 2; -} - -int array_sink2_bad(int arr[]) { - int source = __infer_taint_source(); - return arr[source]; -} - -int array_sink3_bad(int arr[]) { return arr[1 + __infer_taint_source()]; } - -void array_sink4_bad(int arr[]) { - int source = __infer_taint_source(); - skip(1, arr[source]); -} - -void std_array_sink_bad(std::array arr) { - int source = __infer_taint_source(); - arr[source] = 2; -} - -void std_string_sink_bad(std::string str) { - int source = __infer_taint_source(); - str[source] = 'a'; -} - -int stack_smash_bad() { - int source = __infer_taint_source(); - int arr[source]; - return arr[0]; // could read from anywhere in the stack -} - -void gflag_to_stack_allocated_array_bad() { int arr[FLAGS_size]; } - -// if we're not careful, this will re-report the warning in the callee -void read_global_no_double_report_ok() { - int i = FLAGS_size; - gflag_to_stack_allocated_array_bad(); -} - -void strcpy_bad(char* str) { - char* source = getenv("some_var"); - strcpy(str, source); -} - -void memcpy_bad(void* data1, void* data2) { - int source = __infer_taint_source(); - memcpy(data1, data2, source); -} - -void wmemcpy_bad(wchar_t* data1, wchar_t* data2) { - int source = __infer_taint_source(); - wmemcpy(data1, data2, source); -} - -void memmove_bad(void* data1, void* data2) { - int source = __infer_taint_source(); - memmove(data1, data2, source); -} - -void wmemmove_bad(wchar_t* data1, wchar_t* data2) { - int source = __infer_taint_source(); - wmemmove(data1, data2, source); -} - -void memset_bad(char* str) { - int source = __infer_taint_source(); - memset(str, '0', source); -} - -void strncpy_bad(char* str1, char* str2) { - int source = __infer_taint_source(); - strncpy(str1, str2, source); -} -void copies_ok(char* str) { - char* source = getenv("some_var"); - int len = std::min(strlen(str), strlen(source)); - memcpy(str, source, len); - memmove(str, source, len); - memset(str, '0', len); - strncpy(str, source, len); -} - -// these examples used to crash the HIL conversion -char index_of_literal_ok1() { return "foo"[1]; } - -char index_of_literal_ok2() { return "foo"[7]; } - -char index_of_literal_ok3(int i) { return "foo"[i]; } -} // namespace arrays diff --git a/infer/tests/codetoanalyze/cpp/quandary/basics.cpp b/infer/tests/codetoanalyze/cpp/quandary/basics.cpp deleted file mode 100644 index 40b69b701b3..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/basics.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include -#include - -extern void* __infer_taint_source(); -extern void __infer_taint_sink(void*); - -namespace basics { - -class Obj { - public: - void* method_source() { return (void*)0; } - void method_sink(void*) {} - static void* static_source() { return (void*)0; } - static void static_sink(void*) {} - std::string string_source(int i) { return ""; } - static int taint_arg_source(int* arg) { return 1; } - void string_sink(std::string) {} - static std::string* sanitizer1(std::string* input) { return input; } - static std::string sanitizer2(const std::string& input) { return input; } - - std::string field1; - std::string field2; - - void endpoint(std::string source1, void* source2) { - this->string_sink(source1); - __infer_taint_sink(source2); - } -}; - -void* returnSource() { return __infer_taint_source(); } - -void callSink(void* param) { __infer_taint_sink(param); } - -void* id(void* param) { return param; } - -void sourceToSinkDirectBad() { - void* source = __infer_taint_source(); - __infer_taint_sink(source); -} - -void returnSourceToSinkBad() { - void* source = returnSource(); - __infer_taint_sink(source); -} - -void sourceThenCallSinkBad() { - void* source = __infer_taint_source(); - callSink(source); -} - -void propagateBad() { - void* source = __infer_taint_source(); - void* launderedSource = id(source); - callSink(launderedSource); -} - -// make sure specifying external sources/sinks as instance methods works -void object_source_sink_bad(Obj obj) { - void* source = obj.method_source(); - obj.method_sink(source); -} - -// make sure specifying external sources/sinks as static methods works -void static_source_sink_bad(Obj obj) { - void* source = Obj::static_source(); - Obj::static_sink(source); -} - -template -T* template_source() { - return nullptr; -} - -template -void template_sink(T) {} - -void template_source_bad() { - void* source = template_source(); - __infer_taint_sink(source); -} - -void string_source_bad(Obj obj) { - std::string source = obj.string_source(5); - obj.string_sink(source); -} - -void via_field_bad1() { - Obj* obj = new Obj(); - obj->field1 = *template_source(); - template_sink(obj->field1); -} - -void via_field_bad2(Obj* obj) { - obj->field1 = *template_source(); - template_sink(obj->field1); -} - -void via_field_ok1() { - Obj* obj = new Obj(); - obj->field1 = *template_source(); - obj->field1 = nullptr; - template_sink(obj->field1); -} - -void via_field_ok2() { - Obj* obj = new Obj(); - obj->field1 = *template_source(); - template_sink(obj->field2); -} - -template -T* id1(T* t) { - return t; -} - -template -T id2(T t) { - return t; -} - -void via_passthrough_bad1(Obj* obj) { - std::string source = obj->string_source(0); - std::string* source_ptr = &source; - std::string* laundered_source = id1(source_ptr); - obj->string_sink(*laundered_source); -} - -void via_passthrough_bad2(Obj* obj) { - std::string source = obj->string_source(0); - std::string laundered_source = id2(source); - obj->string_sink(laundered_source); -} - -void taint_arg_source_bad() { - int source; - Obj::taint_arg_source(&source); - __infer_taint_sink((void*)source); -} - -void taint_arg_source_ok() { - int source; - int ret = Obj::taint_arg_source(&source); - __infer_taint_sink((void*)ret); // return value is not a source -} - -void via_sanitizer_ok1(Obj* obj) { - std::string* source = &obj->string_source(0); - std::string* sanitized = Obj::sanitizer1(source); - obj->string_sink(*sanitized); -} - -void via_sanitizer_ok2(Obj* obj) { - std::string source = obj->string_source(0); - std::string sanitized = obj->sanitizer2(source); - obj->string_sink(sanitized); -} - -std::string* unsanitized_bad(Obj* obj) { - std::string* source = &obj->string_source(0); - std::string* sanitized = Obj::sanitizer1(source); - obj->string_sink(*source); - return sanitized; -} - -void funCall_bad2(int x, void* t) { __infer_taint_sink(t); } - -void funCall_bad1() { funCall_bad2(0, __infer_taint_source()); } - -void atomic_eq(std::atomic> x, - std::chrono::duration y) { - // this gets translated as operator=(x, y, &tmp_return), which used to cause a - // crash - x = y; -} -struct node { - struct node* prev; - struct node* next; -}; - -// we used to hang on this example before the widening operator was fixed -void loop_ok() { - struct node* init; - struct node* tmp; - - while (1) { - tmp->next = init; - init = tmp; - tmp->prev = init; - } -} - -void ret_void_ok() { return; } - -void ret_void_transitive_ok() { return ret_void_ok(); } - -} // namespace basics diff --git a/infer/tests/codetoanalyze/cpp/quandary/endpoints.cpp b/infer/tests/codetoanalyze/cpp/quandary/endpoints.cpp deleted file mode 100644 index dc1d10cbc30..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/endpoints.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include -#include -#include - -extern void __infer_sql_sink(std::string); -extern void __infer_sql_read_sink(std::string); -extern void __infer_sql_write_sink(std::string); -extern std::string __infer_shell_sanitizer(std::string); -extern std::string __infer_sql_sanitizer(std::string); - -extern void curl_easy_setopt(void*, int, ...); - -struct request { - std::string s; - int i; -}; - -namespace gflags { - -// Mock gflags SetCommandLineOption. -void SetCommandLineOption(const char* name, const char* value) {} -} // namespace gflags - -namespace facebook { -namespace fb303 { -namespace cpp2 { - -class FacebookServiceSvIf { - public: - void service1_endpoint_bad(std::string formal); - void user_controlled_endpoint_to_sql_bad(std::string formal); - void unsanitized_sql_bad(std::string formal); - void sanitized_sql_with_shell_bad(std::string formal); - void service1_endpoint_sql_sanitized_bad(std::string formal); - void service1_endpoint_sql_read_bad(std::string formal); - void service1_endpoint_sql_write_bad(std::string formal); - void service1_endpoint_shell_sanitized_ok(std::string formal); - void service1_endpoint_struct_string_field_bad(request formal); - void open_or_create_c_style_file_bad(const char* filename); - void ofstream_open_file_bad(std::string filename); - void ifstream_open_file_bad(std::string filename); - void fstream_open_file_bad(std::string filename); - void endpoint_to_curl_url_bad(request formal); - void endpoint_to_curl_url_exp_bad(request formal); - void endpoint_to_curl_url_unknown_exp_bad(request formal, int i); - void endpoint_to_curl_other_const_ok(request formal); - void endpoint_to_curl_other_exp_ok(request formal); - void FP_service1_endpoint_struct_int_field_ok(request formal); - void service_this_ok(); - void service_return_param_ok(std::string& _return); - void service3_endpoint_bad(std::string formal); - void service3_endpoint_envchange_putenv_bad(std::string formal); - void service3_endpoint_envchange_setoption_bad(std::string formal); - - private: - void FP_private_not_endpoint_ok(std::string formal) { - system(formal.c_str()); - } -}; - -class FacebookServiceSvAsyncIf { - public: - void service2_endpoint_bad(std::string formal); -}; -} // namespace cpp2 -} // namespace fb303 -} // namespace facebook - -namespace endpoints { - -class Service1 : facebook::fb303::cpp2::FacebookServiceSvIf { - - public: - void service1_endpoint_bad(std::string formal) { - // this should report REMOTE_CODE_EXECUTION_RISK - system(formal.c_str()); - } - - // this is specified as user-controlled in .inferconfig - void user_controlled_endpoint_to_sql_bad(std::string formal) { - // this should report SQL_INJECTION - __infer_sql_sink(formal); - } - - // this is specified as user-controlled in .inferconfig - void user_controlled_endpoint_to_shell_bad(std::string formal) { - // this should report SHELL_INJECTION - system(formal.c_str()); - } - - void unsanitized_sql_bad(std::string formal) { - // this should report REMOTE_CODE_EXECUTION_RISK - __infer_sql_sink(formal); - } - - void sanitized_sql_with_shell_bad(std::string formal) { - // this should report REMOTE_CODE_EXECUTION_RISK - __infer_sql_sink(__infer_shell_sanitizer(formal)); - } - - void service1_endpoint_sql_sanitized_bad(std::string formal) { - // this should report USER_CONTROLLED_SQL_RISK - __infer_sql_sink(__infer_sql_sanitizer(formal)); - } - - void service1_endpoint_sql_read_bad(std::string formal) { - // this should report USER_CONTROLLED_SQL_RISK - __infer_sql_read_sink(formal); - } - - void service1_endpoint_sql_write_bad(std::string formal) { - // this should report USER_CONTROLLED_SQL_RISK - __infer_sql_write_sink(formal); - } - - void service1_endpoint_shell_sanitized_ok(std::string formal) { - system(__infer_shell_sanitizer(formal).c_str()); - } - - void service1_endpoint_struct_string_field_bad(request formal) { - system(formal.s.c_str()); - } - - void open_or_create_c_style_file_bad(const char* filename) { - open(filename, 0); - openat(1, filename, 2); - creat(filename, 3); - fopen(filename, "w"); - freopen(filename, "w", nullptr); - rename(filename, "mud"); - } - - void ofstream_open_file_bad(std::string filename) { - std::ofstream file1(filename); - std::ofstream file2; - file2.open(filename); - } - - void ifstream_open_file_bad(std::string filename) { - std::ifstream file1(filename); - std::ifstream file2; - file2.open(filename); - } - - void fstream_open_file_bad(std::string filename) { - std::fstream file1(filename); - std::fstream file2; - file2.open(filename); - } - - const int CURLOPT_URL = 10002; - - void endpoint_to_curl_url_bad(request formal) { - curl_easy_setopt(nullptr, CURLOPT_URL, formal.s.c_str()); - } - - void endpoint_to_curl_url_exp_bad(request formal) { - curl_easy_setopt(nullptr, 10000 + 2, formal.s.c_str()); - } - - void endpoint_to_curl_url_unknown_exp_bad(request formal, int i) { - curl_easy_setopt(nullptr, i + 17, formal.s.c_str()); - } - - void endpoint_to_curl_other_const_ok(request formal) { - curl_easy_setopt(nullptr, 0, formal.s.c_str()); - } - - void endpoint_to_curl_other_exp_ok(request formal) { - curl_easy_setopt(nullptr, 1 + 2, formal.s.c_str()); - } - - void FP_service1_endpoint_struct_int_field_ok(request formal) { - system(std::to_string(formal.i).c_str()); - } - - void service_this_ok() { - // endpoint object itself should not be treated as tainted - system((const char*)this); - } - - void service_return_param_ok(std::string& _return) { - // dummy return object should not be treated as tainted - system(_return.c_str()); - } - - // shadows a private method of super; not an override, but we'll flag it as - // one because the code that checks for overrides can't see access modifiers. - void FP_private_not_endpoint_ok(std::string formal) { - system(formal.c_str()); - } - - // doesn't override a method from super - void non_override_ok(std::string formal) { system(formal.c_str()); } - - private: - // similar to above, but even easier - void private_non_override_ok(std::string formal) { system(formal.c_str()); } -}; - -class Service2 : facebook::fb303::cpp2::FacebookServiceSvAsyncIf { - - public: - void service2_endpoint_bad(std::string formal) { - // this should report REMOTE_CODE_EXECUTION_RISK - system(formal.c_str()); - } -}; - -class Service3 : Service1 { - public: - void service3_endpoint_bad(std::string formal) { - // this should report REMOTE_CODE_EXECUTION_RISK - system(formal.c_str()); - } - - void service3_endpoint_envchange_putenv_bad(std::string formal) { - // this should report UNTRUSTED_ENVIRONMENT_CHANGE_RISK - putenv(const_cast(formal.c_str())); - } - - void service3_endpoint_envchange_setoption_bad(std::string formal) { - // this should report UNTRUSTED_ENVIRONMENT_CHANGE_RISK - gflags::SetCommandLineOption("teest", formal.c_str()); - } -}; - -} // namespace endpoints diff --git a/infer/tests/codetoanalyze/cpp/quandary/execs.cpp b/infer/tests/codetoanalyze/cpp/quandary/execs.cpp deleted file mode 100644 index 51989a424a5..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/execs.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include -#include -#include - -extern int rand(); - -extern void __infer_sql_sink(std::string query, int i); - -namespace execs { - -// mocking gflags-generated field -extern char* FLAGS_cli_string; - -extern int FLAGS_cli_int; - -int callAllSinks(const char* stringSource, char** arrSource) { - switch (rand()) { - case 1: - return execl(NULL, stringSource); - case 2: - return execl(stringSource, NULL); - case 3: - // just one test for varargs; assume we get it right in the other cases - return execl(NULL, NULL, stringSource); - case 4: - return execlp(NULL, stringSource); - case 5: - return execlp(stringSource, NULL); - case 6: - return execle(NULL, stringSource); - case 7: - return execle(stringSource, NULL); - case 8: - return execv(stringSource, NULL); - case 9: - return execvp(stringSource, NULL); - case 10: - return execv(NULL, arrSource); - case 11: - return execvp(NULL, arrSource); - } - return 0; -} - -int callExecBad() { - const char* stringSource = std::getenv("ENV_VAR"); - char* arrSource[1] = {std::getenv("ENV_VAR")}; - - switch (rand()) { - case 1: - return execl(NULL, stringSource); - case 2: - return execl(stringSource, NULL); - case 3: - // just one test for varargs; assume we get it right in the other cases - return execl(NULL, NULL, stringSource); - case 4: - return execlp(NULL, stringSource); - case 5: - return execlp(stringSource, NULL); - case 6: - return execle(NULL, stringSource); - case 7: - return execle(stringSource, NULL); - case 8: - return execv(stringSource, NULL); - case 9: - return execvp(stringSource, NULL); - case 10: - return execv(NULL, arrSource); - case 11: - return execvp(NULL, arrSource); - case 12: - return execve(stringSource, NULL, NULL); - case 13: - return execve(NULL, arrSource, NULL); - case 14: - return system(stringSource); - case 15: - FILE* f = popen(stringSource, "w"); - return pclose(f); - } - return 0; -} - -extern char* getenv(const char* var); - -void execConstantStringOk() { callAllSinks("something.sh", NULL); } -void customGetEnvOk() { - const char* source = execs::getenv("ENV_VAR"); - return execl(NULL, source); -} - -void exec_string_flag_bad() { execl(FLAGS_cli_string, NULL); } - -void exec_int_flag_ok() { - char buffer[25]; - sprintf(buffer, "foo -i %d", FLAGS_cli_int); - execl(buffer, NULL); -} - -char* return_global() { - char* local = FLAGS_cli_string; - return local; -} - -void exec_string_flag_interproc_bad() { - char* flag = return_global(); - execl(flag, NULL); -} - -void sql_on_env_var_bad() { - std::string source = (std::string)std::getenv("ENV_VAR"); - __infer_sql_sink(source, 0); -} - -void tainted_flag_popen_ok() { - char* tainted = std::getenv("something"); - popen("ls", tainted); // should not warn; -} - -class Obj { - void endpoint(int i, - char c, - std::string s, - char* c_ptr, - char c_arr[], - std::string* s_ptr) { - __infer_sql_sink(nullptr, i); // don't report - __infer_sql_sink(nullptr, c); // don't report - - __infer_sql_sink(s, 0); // report - __infer_sql_sink(*s_ptr, 0); // report - __infer_sql_sink(c_ptr, 0); // report - __infer_sql_sink(c_arr, 0); // report - } -}; -} // namespace execs diff --git a/infer/tests/codetoanalyze/cpp/quandary/expressions.cpp b/infer/tests/codetoanalyze/cpp/quandary/expressions.cpp deleted file mode 100644 index eae1023cc32..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/expressions.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -extern int __infer_taint_source(); -extern void __infer_taint_sink(int); - -namespace expressions { - -void propagate_via_unop1_bad() { - int source = __infer_taint_source(); - int laundered = ~source; - __infer_taint_sink(laundered); -} - -void propagate_via_unop2_bad() { - int source = __infer_taint_source(); - __infer_taint_sink(~source); -} - -void propagate_via_binop1_bad() { - int source = __infer_taint_source(); - int laundered = 5 + source % 7; - __infer_taint_sink(laundered); -} - -void propagate_via_binop2_bad() { - int source1 = __infer_taint_source(); - int source2 = __infer_taint_source(); - int laundered = 1 + source1 / 2 + source2 * 7; - // should report twice - __infer_taint_sink(laundered); -} - -void propagate_via_binop3_bad() { - int source = __infer_taint_source(); - __infer_taint_sink(source - 3); -} - -void call_sink_nested(int formal) { __infer_taint_sink(formal); } - -void propagate_via_binop_nested1_bad() { - int source = ~(__infer_taint_source()); - call_sink_nested(source); -} - -void propagate_via_binop_nested2_bad() { - int source = __infer_taint_source(); - call_sink_nested(~source); -} - -} // namespace expressions diff --git a/infer/tests/codetoanalyze/cpp/quandary/files.cpp b/infer/tests/codetoanalyze/cpp/quandary/files.cpp deleted file mode 100644 index 284974c5133..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/files.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ -#include -#include -#include - -extern void __infer_url_sink(char*); - -namespace files { - -extern char* FLAGS_cli_string; - -void read_file_call_exec_bad1(int length) { - std::ifstream is("test.txt", std::ifstream::binary); - if (is) { - char* buffer = new char[length]; - is.read(buffer, length); - execle(buffer, NULL); - is.close(); - } -} - -void read_file_call_exec_bad2(int length) { - std::ifstream is("test.txt", std::ifstream::binary); - if (is) { - char* buffer = new char[length]; - is.readsome(buffer, length); - execle(buffer, NULL); - is.close(); - } -} - -void read_file_call_exec_bad3(int length) { - std::ifstream is("test.txt", std::ifstream::binary); - if (is) { - char* buffer = new char[length]; - is.getline(buffer, length); - execle(buffer, NULL); - is.close(); - } -} - -// have to do matching on C procnames to make this work -void FN_read_file_call_exec_bad5(int length) { - std::ifstream is("test.txt", std::ifstream::binary); - if (is) { - char* buffer = new char[length]; - is >> buffer; - execle(buffer, NULL); - is.close(); - } -} - -// make sure we handle reads via iostreams too -void read_file_call_exec_bad5(std::iostream is, int length) { - if (is) { - char* buffer = new char[length]; - is.getline(buffer, length); - execle(buffer, NULL); - } -} - -void read_file_from_flag_ok(int length) { - std::ofstream file1(FLAGS_cli_string, std::ifstream::binary); -} - -void url_from_flag_ok() { __infer_url_sink(FLAGS_cli_string); } - -} // namespace files diff --git a/infer/tests/codetoanalyze/cpp/quandary/issues.exp b/infer/tests/codetoanalyze/cpp/quandary/issues.exp deleted file mode 100644 index 89faabd1666..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/issues.exp +++ /dev/null @@ -1,150 +0,0 @@ -codetoanalyze/cpp/quandary/allocs.cpp, allocs::untrusted_malloc_bad, 0, UNTRUSTED_HEAP_ALLOCATION, no_bucket, ERROR, [Return from allocs::allocation_source,Call to malloc with tainted index 0] -codetoanalyze/cpp/quandary/allocs.cpp, allocs::untrusted_calloc_bad1, 0, UNTRUSTED_HEAP_ALLOCATION, no_bucket, ERROR, [Return from allocs::allocation_source,Call to calloc with tainted index 0] -codetoanalyze/cpp/quandary/allocs.cpp, allocs::untrusted_calloc_bad2, 0, UNTRUSTED_HEAP_ALLOCATION, no_bucket, ERROR, [Return from allocs::allocation_source,Call to calloc with tainted index 1] -codetoanalyze/cpp/quandary/allocs.cpp, allocs::untrusted_reaalloc_bad1, 0, UNTRUSTED_HEAP_ALLOCATION, no_bucket, ERROR, [Return from allocs::allocation_source,Call to realloc with tainted index 0] -codetoanalyze/cpp/quandary/allocs.cpp, allocs::untrusted_reaalloc_bad2, 0, UNTRUSTED_HEAP_ALLOCATION, no_bucket, ERROR, [Return from allocs::allocation_source,Call to realloc with tainted index 1] -codetoanalyze/cpp/quandary/allocs.cpp, allocs::untrusted_brk_bad, 0, UNTRUSTED_HEAP_ALLOCATION, no_bucket, ERROR, [Return from allocs::allocation_source,Call to brk with tainted index 0] -codetoanalyze/cpp/quandary/allocs.cpp, allocs::untrusted_sbrk_bad, 0, UNTRUSTED_HEAP_ALLOCATION, no_bucket, ERROR, [Return from allocs::allocation_source,Call to sbrk with tainted index 0] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::array_sink1_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to __array_access with tainted index 0] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::array_sink2_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to __array_access with tainted index 0] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::array_sink3_bad, 0, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to __array_access with tainted index 0] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::array_sink4_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to __array_access with tainted index 0] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::std_array_sink_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to std::array::operator[] with tainted index 1] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::std_string_sink_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to std::basic_string,std::allocator>::operator[] with tainted index 1] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::stack_smash_bad, 2, UNTRUSTED_VARIABLE_LENGTH_ARRAY, no_bucket, ERROR, [Return from __infer_taint_source,Call to __set_array_length with tainted index 1] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::gflag_to_stack_allocated_array_bad, 0, UNTRUSTED_VARIABLE_LENGTH_ARRAY, no_bucket, ERROR, [Return from __global_access,Call to __set_array_length with tainted index 1] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::strcpy_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from getenv,Call to strcpy with tainted index 1] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::memcpy_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to memcpy with tainted index 2] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::wmemcpy_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to wmemcpy with tainted index 2] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::memmove_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to memmove with tainted index 2] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::wmemmove_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to wmemmove with tainted index 2] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::memset_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to memset with tainted index 2] -codetoanalyze/cpp/quandary/arrays.cpp, arrays::strncpy_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to strncpy with tainted index 2] -codetoanalyze/cpp/quandary/basics.cpp, basics::Obj::endpoint, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from basics::Obj::endpoint,Call to basics::Obj::string_sink with tainted index 1] -codetoanalyze/cpp/quandary/basics.cpp, basics::Obj::endpoint, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from basics::Obj::endpoint,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/basics.cpp, basics::sourceToSinkDirectBad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/basics.cpp, basics::returnSourceToSinkBad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source with tainted data return*,Return from basics::returnSource,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/basics.cpp, basics::sourceThenCallSinkBad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to basics::callSink with tainted index 0,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/basics.cpp, basics::propagateBad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to basics::callSink with tainted index 0,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/basics.cpp, basics::object_source_sink_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from basics::Obj::method_source,Call to basics::Obj::method_sink with tainted index 1] -codetoanalyze/cpp/quandary/basics.cpp, basics::static_source_sink_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from basics::Obj::static_source,Call to basics::Obj::static_sink with tainted index 0] -codetoanalyze/cpp/quandary/basics.cpp, basics::template_source_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from basics::template_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/basics.cpp, basics::string_source_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from basics::Obj::string_source,Call to basics::Obj::string_sink with tainted index 1] -codetoanalyze/cpp/quandary/basics.cpp, basics::via_field_bad1, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from basics::template_source,Call to basics::template_sink with tainted index 0] -codetoanalyze/cpp/quandary/basics.cpp, basics::via_field_bad2, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from basics::template_source,Call to basics::template_sink with tainted index 0] -codetoanalyze/cpp/quandary/basics.cpp, basics::via_passthrough_bad1, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from basics::Obj::string_source,Call to basics::Obj::string_sink with tainted index 1] -codetoanalyze/cpp/quandary/basics.cpp, basics::via_passthrough_bad2, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from basics::Obj::string_source,Call to basics::Obj::string_sink with tainted index 1] -codetoanalyze/cpp/quandary/basics.cpp, basics::taint_arg_source_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from basics::Obj::taint_arg_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/basics.cpp, basics::unsanitized_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from basics::Obj::string_source,Call to basics::Obj::string_sink with tainted index 1] -codetoanalyze/cpp/quandary/basics.cpp, basics::funCall_bad1, 0, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to basics::funCall_bad2 with tainted index 1,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::service1_endpoint_bad, 2, SHELL_INJECTION_RISK, no_bucket, ERROR, [Return from endpoints::Service1::service1_endpoint_bad,Call to system with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::user_controlled_endpoint_to_sql_bad, 2, SQL_INJECTION_RISK, no_bucket, ERROR, [Return from endpoints::Service1::user_controlled_endpoint_to_sql_bad,Call to __infer_sql_sink with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::user_controlled_endpoint_to_shell_bad, 2, SHELL_INJECTION_RISK, no_bucket, ERROR, [Return from endpoints::Service1::user_controlled_endpoint_to_shell_bad,Call to system with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::unsanitized_sql_bad, 2, SQL_INJECTION_RISK, no_bucket, ERROR, [Return from endpoints::Service1::unsanitized_sql_bad,Call to __infer_sql_sink with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::sanitized_sql_with_shell_bad, 2, SQL_INJECTION_RISK, no_bucket, ERROR, [Return from endpoints::Service1::sanitized_sql_with_shell_bad,Call to __infer_sql_sink with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::service1_endpoint_sql_sanitized_bad, 2, USER_CONTROLLED_SQL_RISK, no_bucket, ERROR, [Return from endpoints::Service1::service1_endpoint_sql_sanitized_bad,Call to __infer_sql_sink with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::service1_endpoint_sql_read_bad, 2, USER_CONTROLLED_SQL_RISK, no_bucket, ERROR, [Return from endpoints::Service1::service1_endpoint_sql_read_bad,Call to __infer_sql_read_sink with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::service1_endpoint_sql_write_bad, 2, USER_CONTROLLED_SQL_RISK, no_bucket, ERROR, [Return from endpoints::Service1::service1_endpoint_sql_write_bad,Call to __infer_sql_write_sink with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::service1_endpoint_struct_string_field_bad, 1, SHELL_INJECTION_RISK, no_bucket, ERROR, [Return from endpoints::Service1::service1_endpoint_struct_string_field_bad,Call to system with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::open_or_create_c_style_file_bad, 1, UNTRUSTED_FILE_RISK, no_bucket, ERROR, [Return from endpoints::Service1::open_or_create_c_style_file_bad,Call to open with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::open_or_create_c_style_file_bad, 2, UNTRUSTED_FILE_RISK, no_bucket, ERROR, [Return from endpoints::Service1::open_or_create_c_style_file_bad,Call to openat with tainted index 1] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::open_or_create_c_style_file_bad, 3, UNTRUSTED_FILE_RISK, no_bucket, ERROR, [Return from endpoints::Service1::open_or_create_c_style_file_bad,Call to creat with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::open_or_create_c_style_file_bad, 4, UNTRUSTED_FILE_RISK, no_bucket, ERROR, [Return from endpoints::Service1::open_or_create_c_style_file_bad,Call to fopen with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::open_or_create_c_style_file_bad, 5, UNTRUSTED_FILE_RISK, no_bucket, ERROR, [Return from endpoints::Service1::open_or_create_c_style_file_bad,Call to freopen with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::open_or_create_c_style_file_bad, 6, UNTRUSTED_FILE_RISK, no_bucket, ERROR, [Return from endpoints::Service1::open_or_create_c_style_file_bad,Call to rename with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::ofstream_open_file_bad, 1, UNTRUSTED_FILE_RISK, no_bucket, ERROR, [Return from endpoints::Service1::ofstream_open_file_bad,Call to std::basic_ofstream>::basic_ofstream with tainted index 1] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::ofstream_open_file_bad, 3, UNTRUSTED_FILE_RISK, no_bucket, ERROR, [Return from endpoints::Service1::ofstream_open_file_bad,Call to std::basic_ofstream>::open with tainted index 1] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::ifstream_open_file_bad, 1, UNTRUSTED_FILE_RISK, no_bucket, ERROR, [Return from endpoints::Service1::ifstream_open_file_bad,Call to std::basic_ifstream>::basic_ifstream with tainted index 1] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::ifstream_open_file_bad, 3, UNTRUSTED_FILE_RISK, no_bucket, ERROR, [Return from endpoints::Service1::ifstream_open_file_bad,Call to std::basic_ifstream>::open with tainted index 1] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::fstream_open_file_bad, 1, UNTRUSTED_FILE_RISK, no_bucket, ERROR, [Return from endpoints::Service1::fstream_open_file_bad,Call to std::basic_fstream>::basic_fstream with tainted index 1] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::fstream_open_file_bad, 3, UNTRUSTED_FILE_RISK, no_bucket, ERROR, [Return from endpoints::Service1::fstream_open_file_bad,Call to std::basic_fstream>::open with tainted index 1] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::endpoint_to_curl_url_bad, 1, UNTRUSTED_URL_RISK, no_bucket, ERROR, [Return from endpoints::Service1::endpoint_to_curl_url_bad,Call to curl_easy_setopt with tainted index 2] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::endpoint_to_curl_url_exp_bad, 1, UNTRUSTED_URL_RISK, no_bucket, ERROR, [Return from endpoints::Service1::endpoint_to_curl_url_exp_bad,Call to curl_easy_setopt with tainted index 2] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::endpoint_to_curl_url_unknown_exp_bad, 1, UNTRUSTED_URL_RISK, no_bucket, ERROR, [Return from endpoints::Service1::endpoint_to_curl_url_unknown_exp_bad,Call to curl_easy_setopt with tainted index 2] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::FP_service1_endpoint_struct_int_field_ok, 1, SHELL_INJECTION_RISK, no_bucket, ERROR, [Return from endpoints::Service1::FP_service1_endpoint_struct_int_field_ok,Call to system with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service1::FP_private_not_endpoint_ok, 1, SHELL_INJECTION_RISK, no_bucket, ERROR, [Return from endpoints::Service1::FP_private_not_endpoint_ok,Call to system with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service2::service2_endpoint_bad, 2, SHELL_INJECTION_RISK, no_bucket, ERROR, [Return from endpoints::Service2::service2_endpoint_bad,Call to system with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service3::service3_endpoint_bad, 2, SHELL_INJECTION_RISK, no_bucket, ERROR, [Return from endpoints::Service3::service3_endpoint_bad,Call to system with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service3::service3_endpoint_envchange_putenv_bad, 2, UNTRUSTED_ENVIRONMENT_CHANGE_RISK, no_bucket, ERROR, [Return from endpoints::Service3::service3_endpoint_envchange_putenv_bad,Call to putenv with tainted index 0] -codetoanalyze/cpp/quandary/endpoints.cpp, endpoints::Service3::service3_endpoint_envchange_setoption_bad, 2, UNTRUSTED_ENVIRONMENT_CHANGE_RISK, no_bucket, ERROR, [Return from endpoints::Service3::service3_endpoint_envchange_setoption_bad,Call to gflags::SetCommandLineOption with tainted index 1] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 6, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to execl with tainted index 1] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 8, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to execl with tainted index 0] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 11, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to execl with tainted index 2] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 13, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to execlp with tainted index 1] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 15, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to execlp with tainted index 0] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 17, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to execle with tainted index 1] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 19, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to execle with tainted index 0] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 21, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to execv with tainted index 0] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 23, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to execvp with tainted index 0] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 25, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to execv with tainted index 1] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 27, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to execvp with tainted index 1] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 29, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to execve with tainted index 0] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 31, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to execve with tainted index 1] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 33, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to system with tainted index 0] -codetoanalyze/cpp/quandary/execs.cpp, execs::callExecBad, 35, SHELL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to popen with tainted index 0] -codetoanalyze/cpp/quandary/execs.cpp, execs::exec_string_flag_bad, 0, SHELL_INJECTION_RISK, no_bucket, ERROR, [Return from __global_access,Call to execl with tainted index 0] -codetoanalyze/cpp/quandary/execs.cpp, execs::exec_string_flag_interproc_bad, 2, SHELL_INJECTION_RISK, no_bucket, ERROR, [Return from __global_access with tainted data return,Return from execs::return_global,Call to execl with tainted index 0] -codetoanalyze/cpp/quandary/execs.cpp, execs::sql_on_env_var_bad, 2, SQL_INJECTION, no_bucket, ERROR, [Return from getenv,Call to __infer_sql_sink with tainted index 0] -codetoanalyze/cpp/quandary/expressions.cpp, expressions::propagate_via_unop1_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/expressions.cpp, expressions::propagate_via_unop2_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/expressions.cpp, expressions::propagate_via_binop1_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/expressions.cpp, expressions::propagate_via_binop2_bad, 5, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/expressions.cpp, expressions::propagate_via_binop2_bad, 5, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/expressions.cpp, expressions::propagate_via_binop3_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/expressions.cpp, expressions::propagate_via_binop_nested1_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to expressions::call_sink_nested with tainted index 0,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/expressions.cpp, expressions::propagate_via_binop_nested2_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to expressions::call_sink_nested with tainted index 0,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/files.cpp, files::read_file_call_exec_bad1, 5, SHELL_INJECTION, no_bucket, ERROR, [Return from std::basic_istream>::read,Call to execle with tainted index 0] -codetoanalyze/cpp/quandary/files.cpp, files::read_file_call_exec_bad2, 5, SHELL_INJECTION, no_bucket, ERROR, [Return from std::basic_istream>::readsome,Call to execle with tainted index 0] -codetoanalyze/cpp/quandary/files.cpp, files::read_file_call_exec_bad3, 5, SHELL_INJECTION, no_bucket, ERROR, [Return from std::basic_istream>::getline,Call to execle with tainted index 0] -codetoanalyze/cpp/quandary/files.cpp, files::read_file_call_exec_bad5, 4, SHELL_INJECTION, no_bucket, ERROR, [Return from std::basic_istream>::getline,Call to execle with tainted index 0] -codetoanalyze/cpp/quandary/pointers.cpp, pointers::assign_pointer_pass_to_sink_bad1, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source with tainted data @val$0*,Return from pointers::assign_pointer_to_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/pointers.cpp, pointers::assign_pointer_pass_to_sink_bad2, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source with tainted data @val$0*,Return from pointers::assign_pointer_to_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/pointers.cpp, pointers::assign_source_by_reference_bad1, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source with tainted data @val$0*,Return from pointers::assign_source_by_reference,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/pointers.cpp, pointers::assign_source_by_reference_bad2, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source with tainted data @val$0*,Return from pointers::assign_source_by_reference,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/pointers.cpp, pointers::assign_source_by_reference_bad3, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source with tainted data @val$0*,Return from pointers::assign_source_by_reference with tainted data @val$0*,Return from pointers::call_assign_source_by_reference,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/pointers.cpp, pointers::FP_reuse_pointer_as_local_ok, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source with tainted data @val$0*,Return from pointers::reuse_pointer_as_local,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/sanitizers.cpp, sanitizers::escape_sql_to_shell_bad, 3, SHELL_INJECTION, no_bucket, ERROR, [Return from __infer_taint_source,Call to system with tainted index 0] -codetoanalyze/cpp/quandary/sanitizers.cpp, sanitizers::escape_sql_to_url_bad, 3, UNTRUSTED_URL_RISK, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_url_sink with tainted index 0] -codetoanalyze/cpp/quandary/sanitizers.cpp, sanitizers::escape_shell_to_url_bad, 3, UNTRUSTED_URL_RISK, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_url_sink with tainted index 0] -codetoanalyze/cpp/quandary/sanitizers.cpp, sanitizers::escape_url_to_sql_bad, 3, SQL_INJECTION, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_sql_sink with tainted index 0] -codetoanalyze/cpp/quandary/sanitizers.cpp, sanitizers::dead_sanitizer_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/sanitizers.cpp, sanitizers::kill_sanitizer_bad, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::sprintf1_bad, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::sprintf2_bad, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::strcpy1_bad, 3, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to strcpy with tainted index 1] -codetoanalyze/cpp/quandary/strings.cpp, strings::strcpy1_bad, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::strcpy2_bad, 3, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to strcpy with tainted index 1] -codetoanalyze/cpp/quandary/strings.cpp, strings::strcpy2_bad, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::strncpy_bad, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::memcpy_bad, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::memmove_bad, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::memchr_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::constructor1_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::constructor2_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::constructor3_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::concat1_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::concat2_bad, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::concat3_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::append1_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::append2_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::assign1_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::assign2_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::insert1_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::insert2_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::replace1_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::replace2_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::swap_bad, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::format1_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::format2_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::format3_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::format4_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/strings.cpp, strings::format_varargs_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/structs.cpp, structs::struct_source_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/structs.cpp, structs::struct_field_source_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from getenv,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/structs.cpp, structs::read_from_struct_source_field_bad, 2, SHELL_INJECTION, no_bucket, ERROR, [Return from __infer_taint_source,Call to system with tainted index 0] -codetoanalyze/cpp/quandary/unknown_code.cpp, unknown_code::direct_bad, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/unknown_code.cpp, unknown_code::skip_value_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/unknown_code.cpp, unknown_code::skip_pointer_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/unknown_code.cpp, unknown_code::skip_indirect_bad, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink with tainted index 0] -codetoanalyze/cpp/quandary/vectors.cpp, vectors::write_vector_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to std::vector>::operator[] with tainted index 1] -codetoanalyze/cpp/quandary/vectors.cpp, vectors::read_vector_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to std::vector>::operator[] with tainted index 1] diff --git a/infer/tests/codetoanalyze/cpp/quandary/pointers.cpp b/infer/tests/codetoanalyze/cpp/quandary/pointers.cpp deleted file mode 100644 index 073f9dd6d92..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/pointers.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include - -extern std::string* __infer_taint_source(); -extern void __infer_taint_sink(std::string); - -namespace pointers { - -void assign_pointer_to_source(std::string* pointer) { - *pointer = *__infer_taint_source(); -} - -void assign_pointer_pass_to_sink_bad1(std::string* pointer) { - assign_pointer_to_source(pointer); - __infer_taint_sink(*pointer); -} - -void assign_pointer_pass_to_sink_bad2() { - std::string* pointer = new std::string(); - assign_pointer_to_source(pointer); - __infer_taint_sink(*pointer); -} - -void assign_source_by_reference(std::string& reference) { - reference = *__infer_taint_source(); -} - -void assign_source_by_reference_bad1() { - std::string local; - assign_source_by_reference(local); - __infer_taint_sink(local); -} - -void assign_source_by_reference_bad2(std::string formal) { - assign_source_by_reference(formal); - __infer_taint_sink(formal); -} - -void call_assign_source_by_reference(std::string& formal) { - assign_source_by_reference(formal); -} - -void assign_source_by_reference_bad3() { - std::string local; - call_assign_source_by_reference(local); - __infer_taint_sink(local); -} - -void reuse_pointer_as_local(std::string* pointer) { - pointer = __infer_taint_source(); - std::cout << *pointer; -} - -// need to understand that assigning a reference doesn't change the value in the -// caller -void FP_reuse_pointer_as_local_ok(std::string* pointer) { - reuse_pointer_as_local(pointer); - __infer_taint_sink(*pointer); -} - -void funptr_bad0() { - auto f = __infer_taint_sink; - f(*(__infer_taint_source())); -} - -void funptr_helper_bad1(void (*sink)(std::string)) { - sink(*(__infer_taint_source())); -} - -void funptr_bad1() { - auto f = __infer_taint_sink; - funptr_helper_bad1(f); -} - -void funptr_helper_bad2(std::string* (*source)()) { - __infer_taint_sink(*(source())); -} - -void funptr_bad2() { funptr_helper_bad2(__infer_taint_source); } - -void pointer_arithmetic_ok1(int* i) { *(i + 1) = 7; } - -void pointer_arithmetic_ok2(int* i) { *(2 + 7 + 5 + i + 1) = 7; } -} // namespace pointers diff --git a/infer/tests/codetoanalyze/cpp/quandary/sanitizers.cpp b/infer/tests/codetoanalyze/cpp/quandary/sanitizers.cpp deleted file mode 100644 index 1d113e9c35f..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/sanitizers.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include - -extern std::string __infer_taint_source(); - -extern void __infer_sql_sink(std::string); -extern void __infer_taint_sink(std::string); -extern void __infer_url_sink(std::string); - -extern std::string __infer_all_sanitizer(std::string); -extern std::string __infer_shell_sanitizer(std::string); -extern std::string __infer_sql_sanitizer(std::string); -extern std::string __infer_url_sanitizer(std::string); - -namespace sanitizers { - -void escape_sql_to_sql_ok() { - auto source = __infer_taint_source(); - auto sanitized = __infer_sql_sanitizer(source); - __infer_sql_sink(sanitized); -} - -void escape_shell_to_shell_ok() { - auto source = __infer_taint_source(); - auto sanitized = __infer_shell_sanitizer(source); - system(sanitized.c_str()); -} - -void escape_url_to_url_ok() { - auto source = __infer_taint_source(); - auto sanitized = __infer_url_sanitizer(source); - __infer_url_sink(sanitized); -} - -void foo(std::string sanitized) { __infer_url_sink(sanitized); } - -void all_to_all_ok() { - auto source = __infer_taint_source(); - auto sanitized = __infer_all_sanitizer(source); - __infer_taint_sink(sanitized); -} - -// test a few permutations of "wrong sanitizer for this sink" - -void escape_sql_to_shell_bad() { - auto source = __infer_taint_source(); - auto sanitized = __infer_sql_sanitizer(source); - system(sanitized.c_str()); -} - -void escape_sql_to_url_bad() { - auto source = __infer_taint_source(); - auto sanitized = __infer_sql_sanitizer(source); - __infer_url_sink(sanitized); -} - -void escape_shell_to_url_bad() { - auto source = __infer_taint_source(); - auto sanitized = __infer_shell_sanitizer(source); - __infer_url_sink(sanitized); -} - -void escape_url_to_sql_bad() { - auto source = __infer_taint_source(); - auto sanitized = __infer_url_sanitizer(source); - __infer_sql_sink(sanitized); -} - -void dead_sanitizer_bad() { - auto source = __infer_taint_source(); - auto sanitized = __infer_all_sanitizer(source); - __infer_taint_sink(source); // the sink does not use the sanitized value; - // report -} - -void kill_sanitizer_bad() { - auto source = __infer_taint_source(); - auto x = __infer_all_sanitizer(source); - x = __infer_taint_source(); - __infer_taint_sink(x); -} - -void double_sanitize_ok() { - auto source = __infer_taint_source(); - auto x = __infer_all_sanitizer(source); - auto y = __infer_sql_sanitizer(x); - __infer_taint_sink(y); -} - -void FN_sanitize_one_branch_bad(bool b) { - auto source = __infer_taint_source(); - std::string x; - if (b) { - x = source; - } else { - x = __infer_all_sanitizer(source); - } - // we'll fail to report here because sanitizers are a powerset domain - // ideally they would be an inverted powerset domain, but this is - // difficult to pull off because our handling of unknown code implicitly - // relies on the assumption that join should be union - __infer_taint_sink(x); // should report -} - -void sanitize_both_branches_ok(bool b) { - auto source = __infer_taint_source(); - std::string x; - if (b) { - x = __infer_all_sanitizer(source); - } else { - x = __infer_all_sanitizer(source); - } - __infer_taint_sink(x); // does not report -} - -void different_sanitizer_branches_ok(bool b) { - auto source = __infer_taint_source(); - std::string x; - if (b) { - x = __infer_all_sanitizer(source); - } else { - x = __infer_sql_sanitizer(source); - } - __infer_sql_sink(x); -} - -} // namespace sanitizers diff --git a/infer/tests/codetoanalyze/cpp/quandary/strings.cpp b/infer/tests/codetoanalyze/cpp/quandary/strings.cpp deleted file mode 100644 index 227e410005c..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/strings.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include - -extern std::string __infer_taint_source(); -extern void __infer_taint_sink(std::string); - -// tests related to string manipulation, format strings, etc. -namespace strings { - -void sprintf1_bad() { - char laundered_source[50]; - auto source = __infer_taint_source().c_str(); - sprintf(laundered_source, "%s", source); - __infer_taint_sink(laundered_source); -} - -void sprintf2_bad() { - char laundered_source[50]; - auto source = __infer_taint_source().c_str(); - sprintf(laundered_source, "%s%s%d", "a", source, 1); - __infer_taint_sink(laundered_source); -} - -void strcpy1_bad() { - char laundered_source[50]; - auto source = __infer_taint_source().c_str(); - auto copy = strcpy(laundered_source, source); - __infer_taint_sink(copy); -} - -void strcpy2_bad() { - char laundered_source[50]; - auto source = __infer_taint_source().c_str(); - strcpy(laundered_source, source); - __infer_taint_sink(laundered_source); -} - -void strncpy_bad() { - char laundered_source[50]; - auto source = __infer_taint_source().c_str(); - strncpy(laundered_source, source, 50); - __infer_taint_sink(laundered_source); -} - -void memcpy_bad() { - char laundered_source[50]; - auto source = __infer_taint_source().c_str(); - memcpy(laundered_source, source, 50); - __infer_taint_sink(laundered_source); -} - -void memmove_bad() { - char laundered_source[50]; - auto source = __infer_taint_source().c_str(); - auto copy = (char*)memmove(laundered_source, source, 50); - __infer_taint_sink(copy); -} - -void memchr_bad() { - auto source = __infer_taint_source().c_str(); - auto laundered_source = (char*)memchr(source, 'a', 10); - __infer_taint_sink(laundered_source); -} - -void constructor1_bad() { - auto source = __infer_taint_source(); - auto laundered_source = std::string(source); - __infer_taint_sink(laundered_source); -} - -void constructor2_bad() { - auto source = __infer_taint_source(); - auto laundered_source = std::string(source, 0, 5); - __infer_taint_sink(laundered_source); -} - -void constructor3_bad() { - auto source = __infer_taint_source(); - auto laundered_source = std::string(source.begin(), source.begin() + 5); - __infer_taint_sink(laundered_source); -} - -void concat1_bad() { - auto source = __infer_taint_source(); - source += "other string"; - __infer_taint_sink(source); -} - -void concat2_bad() { - auto source = __infer_taint_source(); - auto laundered_source = std::string("string"); - laundered_source += source; - __infer_taint_sink(laundered_source); -} - -void concat3_bad() { - auto source = __infer_taint_source(); - __infer_taint_sink(source += "string"); -} - -void append1_bad() { - auto source = __infer_taint_source(); - __infer_taint_sink(std::string("string").append(source)); -} - -void append2_bad() { - auto source = __infer_taint_source(); - source.append("string"); - __infer_taint_sink(source); -} - -void assign1_bad() { - auto source = __infer_taint_source(); - __infer_taint_sink(std::string("string").assign(source)); -} - -void assign2_bad() { - auto source = __infer_taint_source(); - source.assign("string"); - __infer_taint_sink(source); -} - -void insert1_bad() { - auto source = __infer_taint_source(); - __infer_taint_sink(std::string("string").assign(source)); -} - -void insert2_bad() { - auto source = __infer_taint_source(); - source.insert(0, "string"); - __infer_taint_sink(source); -} - -void replace1_bad() { - auto source = __infer_taint_source(); - __infer_taint_sink(std::string("string").replace(0, 5, source)); -} - -void replace2_bad() { - auto source = __infer_taint_source(); - source.replace(0, 5, "string"); - __infer_taint_sink(source); -} - -void swap_bad() { - auto source = __infer_taint_source(); - auto laundered_source = std::string("string"); - laundered_source.swap(source); - __infer_taint_sink(laundered_source); -} - -template -class Formatter { - - public: - explicit Formatter(std::string str, Args&&... args); - std::string str(); -}; - -template -Formatter format1(std::string fmt, Args&&... args) { - return Formatter(fmt, std::forward(args)...); -} - -template -Formatter* format2(std::string fmt, Args&&... args) { - return new Formatter(fmt, std::forward(args)...); -} - -template -Formatter format3(std::string fmt, Args&&... args); - -template -Formatter* format4(std::string fmt, Args&&... args); - -void format1_bad() { - auto source = __infer_taint_source(); - auto laundered_source = format1("%s", source).str(); - __infer_taint_sink(laundered_source); -} - -void format2_bad() { - auto source = __infer_taint_source(); - auto laundered_source = format2("%s", source)->str(); - __infer_taint_sink(laundered_source); -} - -void format3_bad() { - auto source = __infer_taint_source(); - auto laundered_source = format3("%s", source).str(); - __infer_taint_sink(laundered_source); -} - -void format4_bad() { - auto source = __infer_taint_source(); - auto laundered_source = format4("%s", source)->str(); - __infer_taint_sink(laundered_source); -} - -void format_varargs_bad() { - auto source = __infer_taint_source(); - auto laundered_source = format3("%s%s", "a", source, "b").str(); - __infer_taint_sink(laundered_source); -} -} // namespace strings diff --git a/infer/tests/codetoanalyze/cpp/quandary/structs.cpp b/infer/tests/codetoanalyze/cpp/quandary/structs.cpp deleted file mode 100644 index 9c63a775537..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/structs.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include - -struct mystruct { - char* str; - int i; -}; - -extern mystruct* __infer_taint_source(); -extern void __infer_taint_sink(mystruct); - -namespace structs { - -void struct_source_bad() { - mystruct* source = __infer_taint_source(); - __infer_taint_sink(*source); -} - -void FN_struct_field_source_unique_pointer_bad() { - std::unique_ptr source(__infer_taint_source()); - __infer_taint_sink(*source); -} - -void struct_field_source_bad() { - mystruct source; - source.str = std::getenv("var"); - __infer_taint_sink(source); -} - -void read_from_struct_source_field_bad() { - mystruct* source = __infer_taint_source(); - system(source->str); -} - -} // namespace structs diff --git a/infer/tests/codetoanalyze/cpp/quandary/unknown_code.cpp b/infer/tests/codetoanalyze/cpp/quandary/unknown_code.cpp deleted file mode 100644 index 4093f760973..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/unknown_code.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include -#include - -extern std::string __infer_taint_source(); -extern void __infer_taint_sink(std::string); -extern std::string skip_value(std::string); -extern std::string* skip_pointer(std::string); -extern void skip_by_ref(std::string, std::string&); - -extern int of_string(std::string); - -namespace unknown_code { - -void direct_bad() { - auto source = __infer_taint_source(); - __infer_taint_sink(source); -} - -void skip_value_bad() { - auto source = __infer_taint_source(); - auto laundered_source = skip_value(source); - __infer_taint_sink(laundered_source); -} - -void skip_pointer_bad() { - auto source = __infer_taint_source(); - auto laundered_source = skip_pointer(source); - __infer_taint_sink(*laundered_source); -} - -std::string skip_indirect(std::string formal) { - auto skipped_pointer = skip_pointer(formal); - return skip_value(*skipped_pointer); -} - -void skip_indirect_bad() { - auto source = __infer_taint_source(); - auto laundered_source = skip_indirect(source); - __infer_taint_sink(laundered_source); -} - -// for now, we don't have any heuristics for guessing that laundered_by_ref is -// assigned by ref in -// the skipped function -void FN_via_skip_by_ref_bad() { - auto source = __infer_taint_source(); - std::string laundered_by_ref; - skip_by_ref(source, laundered_by_ref); - __infer_taint_sink(laundered_by_ref); -} - -} // namespace unknown_code diff --git a/infer/tests/codetoanalyze/cpp/quandary/vectors.cpp b/infer/tests/codetoanalyze/cpp/quandary/vectors.cpp deleted file mode 100644 index 912483b6b17..00000000000 --- a/infer/tests/codetoanalyze/cpp/quandary/vectors.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include -#include - -extern int __infer_taint_source(); - -namespace vectors { - -void write_vector_bad(std::vector vec) { - int source = __infer_taint_source(); - vec[source] = 2; -} - -int read_vector_bad(std::vector vec) { - int source = __infer_taint_source(); - return vec[source]; -} - -// don't care about map accesses -void write_map_ok(std::map map) { - int source = __infer_taint_source(); - map[source] = 2; -} - -void write_string_map_ok(std::map map) { - int source = __infer_taint_source(); - map[source] = "string"; -} - -int read_map_ok(std::map map) { - int source = __infer_taint_source(); - return map[source]; -} - -} // namespace vectors diff --git a/infer/tests/codetoanalyze/java/checkers/Makefile b/infer/tests/codetoanalyze/java/checkers/Makefile index b10ef419458..6e43d646a06 100644 --- a/infer/tests/codetoanalyze/java/checkers/Makefile +++ b/infer/tests/codetoanalyze/java/checkers/Makefile @@ -7,7 +7,7 @@ TESTS_DIR = ../../.. INFER_OPTIONS = \ --debug-exceptions --no-default-checkers \ - --fragment-retains-view --printf-args --quandary \ + --fragment-retains-view --printf-args \ --racerd \ INFERPRINT_OPTIONS = --issues-tests diff --git a/infer/tests/codetoanalyze/java/quandary/.inferconfig b/infer/tests/codetoanalyze/java/quandary/.inferconfig deleted file mode 100644 index fc022b86a28..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/.inferconfig +++ /dev/null @@ -1,45 +0,0 @@ -{ - "force-delete-results-dir": true, - "quandary-sources": [ - { - "procedure": "codetoanalyze.java.quandary.ExternalSpecs.privateData*", - "kind": "PrivateData" - }, - { - "procedure": "codetoanalyze.java.quandary.InterfaceSpec.source", - "kinds": ["PrivateData", "Other"] - } - ], - "quandary-sinks": [ - { - "procedure": "codetoanalyze.java.quandary.ExternalSpecs.loggingSink1", - "kind": "Logging", - "index": "1" - }, - { - "procedure": "codetoanalyze.java.quandary.ExternalSpecs.loggingSink2", - "kind": "Logging" - }, - { - "procedure": "codetoanalyze.java.quandary.ExternalSpecs.sinkThatPropagates", - "kind": "Logging" - }, - { - "procedure": "codetoanalyze.java.quandary.InterfaceSpec.sink", - "kind": "Logging" - }, - { - "procedure": "codetoanalyze.java.quandary.ConstructorSink.", - "kind": "Other", - "index": "0" - } - ], - "quandary-sanitizers": [ - { - "procedure": "codetoanalyze.java.quandary.ExternalSpecs.sanitizer" - } - ], - "quandary-endpoints": [ - "codetoanalyze.java.quandary.MyService" - ] -} diff --git a/infer/tests/codetoanalyze/java/quandary/Arrays.java b/infer/tests/codetoanalyze/java/quandary/Arrays.java deleted file mode 100644 index 8598ccf407a..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/Arrays.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import com.facebook.infer.builtins.InferTaint; - -public class Arrays { - - static class Obj { - Object f; - Object[] arr; - } - - /** should report on these tests */ - void viaArrayBad() { - Object[] arr = new Object[1]; - arr[0] = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(arr[0]); - } - - void viaArrayThenFieldBad() { - Obj[] arr = new Obj[1]; - arr[0].f = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(arr[0].f); - } - - void viaFieldThenArrayBad1(Obj obj) { - obj.arr[0] = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(obj.arr[0]); - } - - void viaFieldThenArrayBad2() { - Obj obj = new Obj(); - obj.arr = new Obj[1]; - obj.arr[0] = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(obj.arr[0]); - } - - /** should not report on these tests */ - void viaArrayOk() { - Object[] arr = new Object[1]; - arr[0] = new Object(); - InferTaint.inferSensitiveSink(arr[0]); - } - - /** false positives: an ideal analysis would not report on these, but we do */ - - // we don't track array indices precisely - void FP_viaArrayOk1(Object y, Object[] z) { - Object[] arr = new Object[2]; - arr[0] = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(arr[1]); - } - - // we use weak update semantics on arrays - void FP_viaArrayOk2(Object y, Object[] z) { - Object[] arr = new Object[1]; - arr[0] = InferTaint.inferSecretSource(); - arr[0] = null; - InferTaint.inferSensitiveSink(arr[0]); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/Basics.java b/infer/tests/codetoanalyze/java/quandary/Basics.java deleted file mode 100644 index c823090ec4b..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/Basics.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import com.facebook.infer.builtins.InferTaint; - -/** testing basic intraprocedural functionality: assignment, ifs, loops, casts */ -public class Basics { - - native Object notASource(); - - native void notASink(Object o); - - /** should report on these tests */ - void directBad() { - InferTaint.inferSensitiveSink(InferTaint.inferSecretSource()); - } - - void viaVarBad1() { - Object src = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(src); - } - - void viaVarBad2() { - Object src = InferTaint.inferSecretSource(); - Object alias = src; - InferTaint.inferSensitiveSink(alias); - } - - void viaVarBad3() { - Object src = InferTaint.inferSecretSource(); - Object alias = src; - src = null; - InferTaint.inferSensitiveSink(alias); - } - - void viaCastBad1() { - InferTaint.inferSensitiveSink((String) InferTaint.inferSecretSource()); - } - - void viaCastBad2() { - Object src = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink((String) src); - } - - void ifBad1(boolean b) { - Object src = null; - if (b) { - src = InferTaint.inferSecretSource(); - } - InferTaint.inferSensitiveSink(src); - } - - void ifBad2(boolean b) { - Object src = InferTaint.inferSecretSource(); - if (b) { - src = null; - } - InferTaint.inferSensitiveSink(src); - } - - void ifBad3(boolean b) { - Object src; - if (b) { - src = new Object(); - } else { - src = InferTaint.inferSecretSource(); - } - InferTaint.inferSensitiveSink(src); - } - - void ifBad4(boolean b1, boolean b2) { - Object src; - if (b1) { - src = new Object(); - } else if (b2) { - src = InferTaint.inferSecretSource(); - } else { - src = null; - } - InferTaint.inferSensitiveSink(src); - } - - void ifBad5(boolean b) { - Object src = InferTaint.inferSecretSource(); - if (b) { - InferTaint.inferSensitiveSink(src); - } - } - - void switchBad1(int i) { - Object src = InferTaint.inferSecretSource(); - switch (i) { - case 1: - InferTaint.inferSensitiveSink(src); - break; - case 2: - break; - default: - break; - } - } - - void switchBad2(int i) { - Object src = InferTaint.inferSecretSource(); - switch (i) { - case 1: - break; - case 2: - InferTaint.inferSensitiveSink(src); - break; - default: - break; - } - } - - void switchBad3(int i) { - Object src = null; - switch (i) { - case 1: - src = InferTaint.inferSecretSource(); - // fallthrough - case 2: - InferTaint.inferSensitiveSink(src); - break; - default: - break; - } - } - - void whileBad1(int i) { - Object src = InferTaint.inferSecretSource(); - while (i < 10) { - InferTaint.inferSensitiveSink(src); - i++; - } - } - - void whileBad2(int i) { - Object src = null; - while (i < 10) { - src = InferTaint.inferSecretSource(); - i++; - } - InferTaint.inferSensitiveSink(src); - } - - // this should report only two alarms, not three - void noTripleReportBad() { - Object src = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(src); - InferTaint.inferSensitiveSink(src); - } - - void arrayWithTaintedContentsBad() { - Object src = InferTaint.inferSecretSource(); - Object[] arr = new Object[] {src}; - InferTaint.inferSensitiveSink(arr); - } - - void funCallBad1() { - Object src = InferTaint.inferSecretSource(); - funCallBad2(2, src); - } - - void funCallBad2(int x, Object src) { - InferTaint.inferSensitiveSink(src); - } - - /** should not report on these tests */ - void directOk1() { - notASink(notASource()); - } - - void directOk2() { - notASink(InferTaint.inferSecretSource()); - } - - void directOk3() { - InferTaint.inferSensitiveSink(notASource()); - } - - void viaVarOk() { - Object src = new Object(); - InferTaint.inferSensitiveSink(src); - } - - void viaVarStrongUpdateOk() { - Object src = InferTaint.inferSecretSource(); - src = null; - InferTaint.inferSensitiveSink(src); - } - - Object exceptionOk(boolean b, Object o) { - if (b) { - throw new AssertionError("exception"); - } - o.toString(); - return o; - } - - void synchronizedOk(Object o) { - synchronized (o) { - } - } - - // this is to test that we don't crash due to the slightly odd translation of synchronized - void callSynchronizedOk(Object o) { - synchronizedOk(o); - } - - /** - * "known false positive" tests demonstrating limitations. an ideal analysis would not report on - * these tests, but we do. - */ - void FP_deadCodeOk() { - Object src = InferTaint.inferSecretSource(); - boolean b = false; - if (b) { - InferTaint.inferSensitiveSink(src); - } - } - - void FP_loopInvariantOk() { - Object src = InferTaint.inferSecretSource(); - for (int i = 0; i < 10; i++) { - src = null; - } - InferTaint.inferSensitiveSink(src); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/ClassLoading.java b/infer/tests/codetoanalyze/java/quandary/ClassLoading.java deleted file mode 100644 index 58737277114..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/ClassLoading.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import android.content.ClipboardManager; - -public class ClassLoading { - ClipboardManager clipboard; - - public String getUserControlledString() { - return this.clipboard.getText().toString(); - } - - public void clipboardToClassForNameBad() { - try { - Class cls = Class.forName(this.getUserControlledString()); - } catch (Exception e) { - System.out.println("Exception: " + e); - } - } - - /* - We don't want to report it as we consider that string concatenation - sanitizes the user-controlled string for class loading. - */ - public void clipboardToClassForNameWithConcatenationGood() { - String javaFileName = "blabla." + this.getUserControlledString(); - try { - Class cls = Class.forName(javaFileName); - } catch (Exception e) { - System.out.println("Exception: " + e); - } - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/ContentProviders.java b/infer/tests/codetoanalyze/java/quandary/ContentProviders.java deleted file mode 100644 index 04efb0311aa..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/ContentProviders.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import android.content.ContentProvider; -import android.content.ContentValues; -import android.content.res.AssetFileDescriptor; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; -import android.os.CancellationSignal; -import android.os.ParcelFileDescriptor; -import java.io.File; - -public abstract class ContentProviders extends ContentProvider { - - File mFile; - - @Override - public int bulkInsert(Uri uri, ContentValues[] values) { - mFile = new File(uri.toString()); - return 0; - } - - @Override - public Bundle call(String method, String args, Bundle extras) { - mFile = new File(method); - return extras; - } - - @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { - mFile = new File(uri.toString()); - return 0; - } - - @Override - public Uri insert(Uri uri, ContentValues values) { - mFile = new File(uri.toString()); - return null; - } - - @Override - public String getType(Uri uri) { - mFile = new File(uri.toString()); - return null; - } - - @Override - public AssetFileDescriptor openAssetFile(Uri uri, String mode, CancellationSignal signal) { - mFile = new File(uri.toString()); - return null; - } - - @Override - public ParcelFileDescriptor openFile(Uri uri, String mode, CancellationSignal signal) { - mFile = new File(uri.toString()); - return null; - } - - @Override - public AssetFileDescriptor openTypedAssetFile( - Uri uri, String mimeTypeFilter, Bundle opts, CancellationSignal signal) { - mFile = new File(uri.toString()); - return null; - } - - @Override - public Cursor query( - Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { - mFile = new File(uri.toString()); - return null; - } - - @Override - public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - mFile = new File(uri.toString()); - return 0; - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/DynamicDispatch.java b/infer/tests/codetoanalyze/java/quandary/DynamicDispatch.java deleted file mode 100644 index a9f15cbda32..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/DynamicDispatch.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import com.facebook.infer.builtins.InferTaint; - -public class DynamicDispatch { - - static interface Interface { - public Object returnSource(); - - public void callSink(Object o); - - public Object propagate(Object o); - } - - static class BadInterfaceImpl1 implements Interface { - @Override - public Object returnSource() { - return InferTaint.inferSecretSource(); - } - - @Override - public void callSink(Object o) { - InferTaint.inferSensitiveSink(o); - } - - @Override - public Object propagate(Object o) { - return o; - } - } - - static class BadInterfaceImpl2 implements Interface { - @Override - public Object returnSource() { - return InferTaint.inferSecretSource(); - } - - @Override - public void callSink(Object o) { - InferTaint.inferSensitiveSink(o); - } - - @Override - public Object propagate(Object o) { - return o; - } - } - - static class OkInterfaceImpl implements Interface { - @Override - public Object returnSource() { - return null; - } - - @Override - public void callSink(Object o) {} - - @Override - public Object propagate(Object o) { - return null; - } - } - - /** - * interface tests. for all of these, we should see a warning for both BadInterfaceImpl1 and - * BadInterfaceImpl2, but not OkInterfaceImpl - */ - static void FN_returnSourceViaInterfaceBad(Interface i) { - Object source = i.returnSource(); - InferTaint.inferSensitiveSink(source); - } - - static void FN_callSinkViaInterfaceBad(Interface i) { - Object source = InferTaint.inferSecretSource(); - i.callSink(source); - } - - static void propagateViaInterfaceBad(Interface i) { - Object source = InferTaint.inferSecretSource(); - Object launderedSource = i.propagate(source); - InferTaint.inferSensitiveSink(launderedSource); - } - - static void interfaceOk() { - Interface i = new OkInterfaceImpl(); - Object source1 = i.returnSource(); - InferTaint.inferSensitiveSink(source1); - - Object source2 = InferTaint.inferSecretSource(); - i.callSink(source2); - - Object launderedSource = i.propagate(source2); - InferTaint.inferSensitiveSink(launderedSource); - } - - static class Supertype { - public Object returnSource() { - return null; - } - - public void callSink(Object o) {} - - public Object propagate(Object o) { - return null; - } - } - - static class BadSubtype extends Supertype { - @Override - public Object returnSource() { - return InferTaint.inferSecretSource(); - } - - @Override - public void callSink(Object o) { - InferTaint.inferSensitiveSink(o); - } - - @Override - public Object propagate(Object o) { - return o; - } - } - - static void FN_returnSourceViaSubtypeBad(Supertype s) { - Object source = s.returnSource(); - InferTaint.inferSensitiveSink(source); - } - - static void FN_callSinkViaSubtypeBad(Supertype s) { - Object source = InferTaint.inferSecretSource(); - s.callSink(source); - } - - static void FN_propagateViaSubtypeBad(Supertype s) { - Object source = InferTaint.inferSecretSource(); - Object launderedSource = s.propagate(source); - InferTaint.inferSensitiveSink(launderedSource); - } - - // need to look and see if we know the concrete type of the receiver to get this one - static void propagateViaConcreteTypeOk() { - Supertype s = new Supertype(); - - Object source1 = s.returnSource(); - InferTaint.inferSensitiveSink(source1); - - Object source2 = InferTaint.inferSecretSource(); - s.callSink(source2); - - Object launderedSource = s.propagate(source2); - InferTaint.inferSensitiveSink(launderedSource); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/Exceptions.java b/infer/tests/codetoanalyze/java/quandary/Exceptions.java deleted file mode 100644 index a6817cfb048..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/Exceptions.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import com.facebook.infer.builtins.InferTaint; - -class Exceptions { - - static native void mayExcept() throws Exception; - - public static void sinkInCatchBad1() { - Object source = InferTaint.inferSecretSource(); - try { - mayExcept(); - } catch (Exception e) { - InferTaint.inferSensitiveSink(source); - } - } - - public static void sinkInCatchBad2() { - Object source = null; - try { - source = InferTaint.inferSecretSource(); - mayExcept(); - } catch (Exception e) { - InferTaint.inferSensitiveSink(source); - } - } - - public static void sinkAfterCatchBad() { - Object source = InferTaint.inferSecretSource(); - try { - mayExcept(); - source = null; - } catch (Exception e) { - } - InferTaint.inferSensitiveSink(source); - } - - public static void sinkAfterCatchOk() { - Object source = InferTaint.inferSecretSource(); - try { - mayExcept(); - source = null; - } catch (Exception e) { - source = null; - } - InferTaint.inferSensitiveSink(source); - } - - public static void sinkInFinallyBad1() throws Exception { - Object source = InferTaint.inferSecretSource(); - try { - mayExcept(); - } finally { - InferTaint.inferSensitiveSink(source); - } - } - - public static void sinkInFinallyBad2() throws Exception { - Object source = null; - try { - mayExcept(); - source = InferTaint.inferSecretSource(); - } finally { - InferTaint.inferSensitiveSink(source); - } - } - - public static void sinkInFinallyBad3() { - Object source = null; - try { - mayExcept(); - } catch (Exception e) { - source = InferTaint.inferSecretSource(); - } finally { - InferTaint.inferSensitiveSink(source); - } - } - - public static void sinkAfterFinallyOk1() throws Exception { - Object source = InferTaint.inferSecretSource(); - try { - mayExcept(); - } finally { - source = null; - } - InferTaint.inferSensitiveSink(source); - } - - public static void sinkAfterFinallyOk2() { - Object source = null; - try { - mayExcept(); - source = InferTaint.inferSecretSource(); - } catch (Exception e) { - source = InferTaint.inferSecretSource(); - } finally { - source = null; - } - InferTaint.inferSensitiveSink(source); - } - - public static void callSinkThenThrow(Object param) throws Exception { - InferTaint.inferSensitiveSink(param); - throw new Exception(); - } - - public static void callSinkThenThrowBad() throws Exception { - callSinkThenThrow(InferTaint.inferSecretSource()); - } - - public static void doThrow(Object param) throws RuntimeException { - throw new RuntimeException(param.toString()); - } - - // false negative; need to track flow into and out of exceptions to get this (t14159157) - public static void FN_callSink() { - try { - doThrow(InferTaint.inferSecretSource()); - } catch (RuntimeException e) { - InferTaint.inferSensitiveSink(e); - } - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/ExternalSpecs.java b/infer/tests/codetoanalyze/java/quandary/ExternalSpecs.java deleted file mode 100644 index 6d1467fd6fa..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/ExternalSpecs.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import android.app.Activity; -import android.content.Intent; -import android.util.Log; -import com.facebook.infer.builtins.InferTaint; - -/** Testing that sources and sinks specified in external JSON work correctly */ -public class ExternalSpecs { - - // we specify this as a source with kind PrivateData in .inferconfig - private static Object privateDataSource() { - return new Object(); - } - - public static void logExternalSourceBad() { - Log.e("", (String) privateDataSource()); - } - - // we specified that this is a private data source, so passing it an intent sink like - // startActivity() is fine - public static void externalSourceAsIntentOk(Activity activity) { - activity.startActivity((Intent) privateDataSource()); - } - - // we specify that index 1 is an external sink with type Logging in .inferconfig - public static void loggingSink1(Object notASink, Object sink) {} - - public static void callExternalSinkBad() { - loggingSink1(null, privateDataSource()); - } - - // passing to non-tainted param - public static void callExternalSinkOk1() { - loggingSink1(privateDataSource(), null); - } - - // passing intent source to logging sink is fine - public static void callExternalSinkOk2(Activity activity) { - loggingSink1(null, activity.getIntent()); - } - - // we specify that all the indices are tainted with type Logging in .inferconfig - public static void loggingSink2(Object sink1, Object sink2) {} - - public static void callExternalSink2Bad1() { - loggingSink2(privateDataSource(), null); - } - - public static void callExternalSink2Bad2() { - loggingSink2(null, privateDataSource()); - } - - // passing intent sources to logging sink is fine - public static void callExternalSink2Ok(Activity activity) { - loggingSink2(activity.getIntent(), activity.getIntent()); - } - - static Object sanitizer(Object o) { - return o; - } - - void viaSanitizerOk() { - Object source = InferTaint.inferSecretSource(); - Object sanitized = sanitizer(source); - InferTaint.inferSensitiveSink(sanitized); - } - - void sanitizeFootprint(Object o) { - Object sanitized = sanitizer(o); - InferTaint.inferSensitiveSink(sanitized); - } - - void callSanitizeFootprintOk() { - sanitizeFootprint(InferTaint.inferSecretSource()); - } - - Object returnSanitizedSource() { - Object source = InferTaint.inferSecretSource(); - return sanitizer(source); - } - - void callSinkOnSanitizedSourceOk() { - InferTaint.inferSensitiveSink(returnSanitizedSource()); - } - - Object missedSanitizerBad() { - Object source = InferTaint.inferSecretSource(); - Object sanitized = sanitizer(source); - InferTaint.inferSensitiveSink(source); - return sanitized; - } - - void FN_sanitizeOneBranchBad(boolean b) { - Object source = InferTaint.inferSecretSource(); - Object o; - if (b) { - o = sanitizer(source); - } else { - o = source; - } - InferTaint.inferSensitiveSink(o); - } - - Object sanitizeOneBranchInCallee(Object o, boolean b) { - if (b) { - return sanitizer(o); - } else { - return o; - } - } - - void FN_sanitizerWeakUpdateBad(boolean b) { - Object source = InferTaint.inferSecretSource(); - Object o = sanitizeOneBranchInCallee(source, b); - InferTaint.inferSensitiveSink(o); - } - - // if theres' a procedure with the same name defined in .inferconfig as a sink on parameter 1, - // we shouldn't crash - public static void loggingSink1() {} - - // we shouldn't fail when calling this either - public static void loggingSink1(Object notASink) {} - - void callLoggingSink1sOk(Object o) { - loggingSink1(); - loggingSink1(o); - } - - public static Object sinkThatPropagates(Object o) { - return o; - } - - void callSinkThatPropagatesBad() { - Object source = InferTaint.inferSecretSource(); - Object sourceAgain = sinkThatPropagates(source); // should report - loggingSink1(null, sourceAgain); // should report here too - } -} - -interface InterfaceSpec { - - // marked as source in .inferconfig - public Object source(); - - // marked as sink in .inferconfig - public void sink(Object o); -} - -class InterfaceSpecImpl implements InterfaceSpec { - - @Override - public Object source() { - return null; - } - - @Override - public void sink(Object o) {} - - public void externalSpecBad() { - sink(source()); - } -} - -class ConstructorSink { - - // specified as a source in .inferconfig - public ConstructorSink(Object o) {} - - public static ConstructorSink constructorSinkBad() { - Object source = InferTaint.inferSecretSource(); - return new ConstructorSink(source); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/Fields.java b/infer/tests/codetoanalyze/java/quandary/Fields.java deleted file mode 100644 index f5b4100f713..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/Fields.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import com.facebook.infer.builtins.InferTaint; - -public class Fields { - - static class Obj { - Object f; - Obj g; - } - - Object mFld; - static Object sFld; - - /** should report on these tests */ - void instanceFieldBad() { - this.mFld = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(this.mFld); - } - - void staticFieldBad() { - sFld = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(sFld); - } - - void viaFieldBad1(Obj obj) { - obj.f = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(obj.f); - } - - void viaFieldBad2() { - Obj obj = new Obj(); - obj.f = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(obj.f); - } - - void viaFieldBad3() { - Obj obj = new Obj(); - obj.f = InferTaint.inferSecretSource(); - Object src = obj.f; - InferTaint.inferSensitiveSink(src); - } - - void viaNestedFieldBad1(Obj obj) { - obj.g.f = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(obj.g.f); - } - - void viaNestedFieldBad2() { - Obj obj = new Obj(); - obj.g = new Obj(); - obj.g.f = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(obj.g.f); - } - - /** should not report on these tests */ - void viaFieldOk() { - Obj obj = new Obj(); - obj.f = InferTaint.inferSecretSource(); - obj.g = new Obj(); - InferTaint.inferSensitiveSink(obj.g); - } - - void viaFieldStrongUpdateOk() { - Obj obj = new Obj(); - obj.f = InferTaint.inferSecretSource(); - obj.f = null; - InferTaint.inferSensitiveSink(obj.f); - } - - void viaNestedFieldOK1(Obj obj) { - obj.g.f = InferTaint.inferSecretSource(); - obj.g.f = null; - InferTaint.inferSensitiveSink(obj.g.f); - } - - void viaNestedFieldOK2() { - Obj obj = new Obj(); - obj.g = new Obj(); - obj.g.f = InferTaint.inferSecretSource(); - obj.g.f = null; - InferTaint.inferSensitiveSink(obj.g.f); - } - - /** an ideal analysis would report on these tests, but we currently do not */ - - // need to soundly handle aliasing to get these examples - - void FN_aliasBad1() { - Obj obj1 = new Obj(); - Obj obj2 = obj1; - obj2.f = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(obj1.f); - } - - void FN_aliasBad2(Obj obj) { - Obj x = obj.g; - x.f = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(obj.g.f); - } - - // need to fix our widening in order to report on this - - void FN_loopFieldBad(Obj obj, int i) { - Obj loopObj = obj; - while (i < 10) { - loopObj.f = InferTaint.inferSecretSource(); - loopObj = loopObj.g; - i++; - } - InferTaint.inferSensitiveSink(obj.g.g.f); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/Files.java b/infer/tests/codetoanalyze/java/quandary/Files.java deleted file mode 100644 index e379322c0b9..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/Files.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import com.facebook.infer.builtins.InferTaint; -import java.io.File; -import java.nio.file.FileSystems; -import java.nio.file.Path; -import java.nio.file.Paths; - -public class Files { - - public File fileConstructorSinkBad() { - String taintedString = (String) InferTaint.inferSecretSource(); - return new File(taintedString); - } - - public Path fileSystemConstructorSinkBad1() { - String taintedString = (String) InferTaint.inferSecretSource(); - return FileSystems.getDefault().getPath(taintedString); - } - - // testing varags - public Path fileSystemConstructorSinkBad2() { - String taintedString = (String) InferTaint.inferSecretSource(); - return FileSystems.getDefault().getPath("", taintedString); - } - - public Path pathsSinkBad1() { - String taintedString = (String) InferTaint.inferSecretSource(); - return Paths.get(taintedString); - } - - // testing varags - public Path pathsSinkBad2() { - String taintedString = (String) InferTaint.inferSecretSource(); - return Paths.get("", taintedString); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/FlowSensitivity.java b/infer/tests/codetoanalyze/java/quandary/FlowSensitivity.java deleted file mode 100644 index 90c5ce5d4ef..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/FlowSensitivity.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import com.facebook.infer.builtins.InferTaint; - -/** making sure the traces we report respect control-flow */ -class FlowSensitivity { - - static class Obj { - Object f; - } - - static void callSink(Obj o) { - InferTaint.inferSensitiveSink(o.f); - } - - static void returnSource(Obj o) { - o.f = InferTaint.inferSecretSource(); - } - - static void interproceduralFlowSensitivityOk1(Obj o) { - InferTaint.inferSensitiveSink(o.f); - returnSource(o); - } - - static void interproceduralFlowSensitivityOk2(Obj o) { - callSink(o); - o.f = InferTaint.inferSecretSource(); - } - - static void interproceduralFlowSensitivityOk3(Obj o) { - callSink(o); - returnSource(o); - } - - static void interproceduralFlowSensitivityBad(Obj o) { - returnSource(o); - callSink(o); - } - - static void sourceAndSink(Obj o) { - InferTaint.inferSensitiveSink(o.f); - o.f = InferTaint.inferSecretSource(); - } - - static void callSourceAndSinkOk(Obj o) { - sourceAndSink(o); - } - - static void callSourceAndSinkBad1(Obj o) { - sourceAndSink(o); - InferTaint.inferSensitiveSink(o.f); - } - - static void callSourceAndSinkBad2(Obj o) { - o.f = InferTaint.inferSecretSource(); - sourceAndSink(o); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/Hil.java b/infer/tests/codetoanalyze/java/quandary/Hil.java deleted file mode 100644 index 6294cd36f81..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/Hil.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import java.util.ArrayList; -import java.util.List; - -/** - * Repro of HIL bindings issue: In the exception node, the invariant that a bound variable cannot - * appear in the RHS of another binding is broken. - */ -class Hil { - public static void foo() { - List Y = new ArrayList<>(); - int dummy = 0; - for (Character x : "X".toCharArray()) { - dummy = 1; - } - for (Integer y : Y) { - dummy = 2; - } - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/Intents.java b/infer/tests/codetoanalyze/java/quandary/Intents.java deleted file mode 100644 index 565017775a3..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/Intents.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import android.app.Activity; -import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentSender.SendIntentException; -import android.net.Uri; -import android.os.Bundle; -import android.os.IBinder; -import com.facebook.infer.builtins.InferTaint; -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.List; -import org.xmlpull.v1.XmlPullParserException; - -class IntentSubclass extends Intent {} - -abstract class ContextSubclass extends Context {} - -class MyActivity extends Activity { - - @Override - // intent is modeled as tainted - public void onActivityResult(int requestCode, int resultCode, Intent intent) { - startService(intent); - } - - @Override - // intent is modeled as tainted - public void onNewIntent(Intent intent) { - startService(intent); - } - - private BroadcastReceiver mReceiver; - private Uri mUri; - - @Override - public void onCreate(Bundle savedInstanceState) { - mReceiver = - new BroadcastReceiver() { - @Override - // intent is modeled as tainted - public void onReceive(Context context, Intent intent) { - mUri = intent.getData(); - } - }; - registerReceiver(mReceiver, null); - } - - @Override - public void onResume() { - startServiceWithTaintedIntent(); - } - - void startServiceWithTaintedIntent() { - Intent taintedIntent = new Intent("", mUri); - startService(taintedIntent); - } -} - -class MyBroadcastReceiver extends BroadcastReceiver { - - Activity mActivity; - - @Override - // intent is modeled as tainted - public void onReceive(Context context, Intent intent) { - mActivity.startService(intent); - } -} - -class MyService extends Service { - - Activity mActivity; - - @Override - // intent is modeled as tainted - public IBinder onBind(Intent intent) { - mActivity.startService(intent); - return null; - } - - @Override - // intent is modeled as tainted - public void onRebind(Intent intent) { - mActivity.startService(intent); - } - - @Override - // intent is modeled as tainted - public void onStart(Intent intent, int startId) { - mActivity.startService(intent); - } - - @Override - // intent is modeled as tainted - public int onStartCommand(Intent intent, int flags, int startId) { - mActivity.startService(intent); - return 0; - } - - @Override - // intent is modeled as tainted - public void onTaskRemoved(Intent intent) { - mActivity.startService(intent); - } - - @Override - // intent is modeled as tainted - public boolean onUnbind(Intent intent) { - mActivity.startService(intent); - return false; - } -} - -public class Intents { - - private native int rand(); - - public void callAllActivitySinksBad(Activity activity, String uri) - throws SendIntentException, IOException, URISyntaxException, XmlPullParserException { - Intent intent = (Intent) InferTaint.inferSecretSource(); - - activity.bindService(intent, null, 0); - activity.sendBroadcast(intent); - activity.sendBroadcastAsUser(intent, null); - activity.sendOrderedBroadcast(intent, null); - activity.sendOrderedBroadcastAsUser(intent, null, null, null, null, 0, null, null); - activity.sendStickyBroadcast(intent); - activity.sendStickyBroadcastAsUser(intent, null); - activity.sendStickyOrderedBroadcast(intent, null, null, 0, null, null); - activity.sendStickyOrderedBroadcastAsUser(intent, null, null, null, 0, null, null); - activity.startActivities(new Intent[] {intent}); - activity.startActivity(intent); - activity.startActivityForResult(intent, 0); - activity.startActivityIfNeeded(intent, 0); - activity.startActivityFromChild(null, intent, 0); - activity.startActivityFromFragment(null, intent, 0); - activity.startIntentSender(null, intent, 0, 0, 0); - activity.startIntentSenderForResult(null, 0, intent, 0, 0, 0); - activity.startIntentSenderFromChild(null, null, 0, intent, 0, 0, 0); - activity.startService(intent); - activity.stopService(intent); // 20 sinks, 20 expected reports - } - - public void callAllIntentSinks() throws IOException, URISyntaxException, XmlPullParserException { - String taintedString = (String) InferTaint.inferSecretSource(); - Intent.parseUri(taintedString, 0); - Intent.getIntent(taintedString); - Intent.getIntentOld(taintedString); - - Uri taintedUri = (Uri) InferTaint.inferSecretSource(); - Intent i = new Intent(); - i.setClassName(taintedString, ""); - i.setData(taintedUri); - i.setDataAndNormalize(taintedUri); - i.setDataAndType(taintedUri, ""); - i.setDataAndTypeAndNormalize(taintedUri, ""); - i.setPackage(taintedString); // 9 sinks, 9 expected reports - } - - // make sure the rules apply to subclasses of Intent and Context too - void subclassCallBad(IntentSubclass intent, ContextSubclass context) { - String taintedString = (String) InferTaint.inferSecretSource(); - intent.setAction(taintedString); - context.startActivity(intent); - } - - void reuseIntentBad(Activity activity) { - activity.startActivity(activity.getIntent()); - } - - Activity mActivity; - - void extraToDataBad() { - Intent taintedIntent = (Intent) InferTaint.inferSecretSource(); - String extra = taintedIntent.getStringExtra("foo"); - - Intent newIntent1 = new Intent(); - newIntent1.setData(Uri.parse(extra)); // should report - Intent newIntent2 = new Intent(); - newIntent2.setData(Uri.parse(extra)); // should report - } - - void extraToExtraOk() { - Intent taintedIntent = (Intent) InferTaint.inferSecretSource(); - String extra = taintedIntent.getStringExtra("foo"); - - Intent newIntent = new Intent(); - newIntent.putExtra("foo", extra); - mActivity.startActivity(newIntent); - } - - List mIntents; - - Context mContext; - - void callStartWithArrayOk() { - Intent[] intents = mIntents.toArray(new Intent[mIntents.size()]); - intents[0] = new Intent(intents[0]).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - if (startWithArrayOk(mContext, intents)) { - mContext.startActivity(intents[1]); - } - } - - boolean startWithArrayOk(Context context, Intent[] newIntents) { - context.startActivities(newIntents, null); - return true; - } - - void startWithClassLiteralOk() { - mActivity.startActivity(new Intent(mActivity, MyActivity.class)); - } - - void startWithUri1Bad(Uri uri) { - mActivity.startActivity(new Intent("action", uri)); - } - - void startWithUri2Bad(Uri uri) { - mActivity.startActivity(new Intent("action", uri, mActivity, MyActivity.class)); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/Interprocedural.java b/infer/tests/codetoanalyze/java/quandary/Interprocedural.java deleted file mode 100644 index fd119b537a1..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/Interprocedural.java +++ /dev/null @@ -1,422 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import com.facebook.infer.builtins.InferTaint; - -class Interprocedural { - - Object f; - - static Object sGlobal; - - static class Obj { - Object f; - } - - public static Object id(Object param) { - return param; - } - - /** source tests */ - public static Object returnSourceDirect() { - return InferTaint.inferSecretSource(); - } - - public static Object returnSourceIndirect() { - return returnSourceDirect(); - } - - public static void returnSourceDirectBad() { - InferTaint.inferSensitiveSink(returnSourceDirect()); - } - - public static void returnSourceDirectViaVarBad() { - Object source = returnSourceDirect(); - InferTaint.inferSensitiveSink(source); - } - - public static void returnSourceIndirectBad() { - InferTaint.inferSensitiveSink(returnSourceIndirect()); - } - - public static Obj returnSourceViaField() { - Obj o = new Obj(); - o.f = InferTaint.inferSecretSource(); - return o; - } - - public static void returnSourceViaFieldBad() { - InferTaint.inferSensitiveSink(returnSourceViaField().f); - } - - public static void returnSourceViaParameter1(Obj o) { - o.f = InferTaint.inferSecretSource(); - } - - public static void returnSourceViaParameter1Bad(Obj o) { - returnSourceViaParameter1(o); - InferTaint.inferSensitiveSink(o.f); - } - - public static void returnSourceViaParameter2(Obj o1, Obj o2) { - o2.f = o1.f; - } - - public static void returnSourceViaParameter2Bad(Obj o1, Obj o2) { - o1.f = InferTaint.inferSecretSource(); - returnSourceViaParameter2(o1, o2); - InferTaint.inferSensitiveSink(o2.f); - } - - public static void returnSourceViaParameterOk(Obj o1, Obj o2) { - o1.f = InferTaint.inferSecretSource(); - returnSourceViaParameter2(o2, o1); - InferTaint.inferSensitiveSink(o2.f); - } - - public static void returnSourceViaGlobal() { - sGlobal = InferTaint.inferSecretSource(); - } - - public void returnSourceViaGlobalBad() { - returnSourceViaGlobal(); - InferTaint.inferSensitiveSink(sGlobal); - } - - public void returnSourceViaGlobalOk() { - returnSourceViaGlobal(); - sGlobal = null; - InferTaint.inferSensitiveSink(sGlobal); - } - - /** sink tests */ - public static void callSinkParam1(Object param1, Object param2) { - InferTaint.inferSensitiveSink(param1); - } - - public static void callSinkParam1Bad() { - callSinkParam1(InferTaint.inferSecretSource(), null); - } - - public static void callSinkParam1Ok() { - callSinkParam1(null, InferTaint.inferSecretSource()); - } - - public static void callSinkParam2(Object param1, Object param2) { - InferTaint.inferSensitiveSink(param2); - } - - public static void callSinkParam2Bad() { - callSinkParam2(null, InferTaint.inferSecretSource()); - } - - public static void callSinkParam2Ok() { - callSinkParam2(InferTaint.inferSecretSource(), null); - } - - public void callSinkOnFieldDirect() { - InferTaint.inferSensitiveSink(this.f); - } - - public void callSinkOnFieldDirectBad() { - this.f = InferTaint.inferSecretSource(); - callSinkOnFieldDirect(); - } - - public static void callSinkOnFieldIndirect(Obj param) { - InferTaint.inferSensitiveSink(param.f); - } - - public static void callSinkOnFieldIndirectBad() { - Obj obj = new Obj(); - obj.f = InferTaint.inferSecretSource(); - callSinkOnFieldIndirect(obj); - } - - public Object getF() { - return f; - } - - void callSinkOnLocal() { - Object local = this.getF(); - InferTaint.inferSensitiveSink(local); - } - - void callSinkOnLocalBad() { - this.f = InferTaint.inferSecretSource(); - callSinkOnLocal(); - } - - public static void callSinkOnGlobal() { - InferTaint.inferSensitiveSink(sGlobal); - } - - public static void callSinkOnGlobalBad() { - sGlobal = InferTaint.inferSecretSource(); - callSinkOnGlobal(); - } - - public static void callSinkOnGlobalOk() { - sGlobal = InferTaint.inferSecretSource(); - sGlobal = null; - callSinkOnGlobal(); - } - - public static void setGlobal(Object o) { - sGlobal = o; - } - - public static void setGlobalThenCallSinkBad() { - setGlobal(InferTaint.inferSecretSource()); - callSinkOnGlobal(); - } - - public static Object getGlobal() { - return sGlobal; - } - - public static void getGlobalThenCallSink() { - Object local = getGlobal(); - InferTaint.inferSensitiveSink(sGlobal); - } - - public static void getGlobalThenCallSinkBad() { - sGlobal = InferTaint.inferSecretSource(); - getGlobalThenCallSink(); - } - - // this should report two alarms, not three - public void callSinkNoTripleReportBad() { - Object source = InferTaint.inferSecretSource(); - callSinkParam1(source, null); - callSinkParam2(null, source); - } - - /** passthrough tests */ - public static void singlePassthroughBad() { - Object source = InferTaint.inferSecretSource(); - Object launderedSource = id(source); - InferTaint.inferSensitiveSink(launderedSource); - } - - public static void doublePassthroughBad() { - Object source = InferTaint.inferSecretSource(); - Object launderedSource1 = id(source); - Object launderedSource2 = id(launderedSource1); - InferTaint.inferSensitiveSink(launderedSource2); - } - - /** false positives: an ideal analysis would not report these, but we will */ - public static Object returnSourceConditional(boolean b) { - if (b) return InferTaint.inferSecretSource(); - return null; - } - - public static void FP_trackParamsOk() { - InferTaint.inferSensitiveSink(returnSourceConditional(false)); - } - - public static void reassignInCallee(Obj o) { - o.f = null; - } - - public static void FP_reassignInCallee() { - Obj o = new Obj(); - o.f = InferTaint.inferSecretSource(); - reassignInCallee(o); - InferTaint.inferSensitiveSink(o.f); - } - - static Object relevantPassthrough(Object param) { - return param; - } - - static Object irrelevantPassthrough(Object param) { - return param; - } - - // the following tests should show only "relevantPassthrough" in their traces - public static Object irrelevantPassthroughsIntraprocedural(Object param) { - Object irrelevant = irrelevantPassthrough(param); - Object source = InferTaint.inferSecretSource(); - Object relevant = relevantPassthrough(source); - InferTaint.inferSensitiveSink(relevant); - return irrelevantPassthrough(relevant); - } - - public static Object returnSourceIrrelevantPassthrough(Object param) { - Object irrelevant = irrelevantPassthrough(param); - Object source = InferTaint.inferSecretSource(); - return relevantPassthrough(source); - } - - public static Object irrelevantPassthroughsSourceInterprocedural(Object o) { - Object irrelevant = irrelevantPassthrough(o); - Object source = returnSourceIrrelevantPassthrough(irrelevant); - Object relevant = relevantPassthrough(source); - InferTaint.inferSensitiveSink(relevant); - return irrelevantPassthrough(source); - } - - public static Object callSinkIrrelevantPassthrough(Object param) { - Object relevant = relevantPassthrough(param); - InferTaint.inferSensitiveSink(relevant); - Object irrelevant = irrelevantPassthrough(param); - return irrelevant; - } - - public static Object irrelevantPassthroughsSinkInterprocedural(Object o) { - Object source = InferTaint.inferSecretSource(); - Object relevant = relevantPassthrough(source); - callSinkIrrelevantPassthrough(relevant); - return irrelevantPassthrough(relevant); - } - - public static Object irrelevantPassthroughsSourceAndSinkInterprocedural(Object o) { - Object irrelevant = irrelevantPassthrough(o); - Object source = returnSourceIrrelevantPassthrough(irrelevant); - Object relevant = relevantPassthrough(source); - callSinkIrrelevantPassthrough(relevant); - return irrelevantPassthrough(relevant); - } - - /** false negatives: an ideal analysis would report on these, but we do not */ - - // this gets modeled as Object[] params in Java. need to treat the array is tainted if its - // contents are tainted in order to get this (t13493230). - public static void callSinkVariadic(Object... params) { - InferTaint.inferSensitiveSink(params); - } - - public static void callSinkVariadicBad() { - callSinkVariadic(null, null, InferTaint.inferSecretSource()); - } - - void diverge() { - for (; ; ) ; - } - - // we don't propagate divergence in callees to callers - public void FP_divergenceInCallee() { - Object source = InferTaint.inferSecretSource(); - diverge(); - InferTaint.inferSensitiveSink(source); - } - - public static void callSinkThenDiverge(Object param) { - InferTaint.inferSensitiveSink(param); - for (; ; ) ; - } - - public void callSinkThenDivergeBad() { - callSinkThenDiverge(InferTaint.inferSecretSource()); - } - - public void callSinkOnParam(Object o) { - InferTaint.inferSensitiveSink(o); - } - - public void callSinkIndirectOnParam(Object o) { - callSinkOnParam(o); - } - - Obj propagate(Object param) { - Obj o = new Obj(); - o.f = param; - return o; - } - - static Obj id2(Obj o) { - return o; - } - - void callSinkA(Obj o) { - callSink1(o); - } - - void callSinkB(Obj o) { - callSink2(o); - } - - void callSinkC(Obj o) { - callSink3(o); - } - - void callSinkD(Obj o) { - callSink4(o); - } - - void callSink1(Obj o) { - InferTaint.inferSensitiveSink(id(o)); - } - - void callSink2(Obj o) { - InferTaint.inferSensitiveSink(id2(o).f); - } - - void callSink3(Obj o) { - InferTaint.inferSensitiveSink(id(o.f)); - } - - void callSink4(Obj o) { - InferTaint.inferSensitiveSink(o.f); - } - - public void callDeepSinkIndirectBad() { - Object source = InferTaint.inferSecretSource(); - callSinkIndirectOnParam(source); - } - - public void callDeepSink1Bad() { - Obj source = propagate(InferTaint.inferSecretSource()); - callSinkA(source); - } - - public void FN_callDeepSink2Bad() { - Obj source = propagate(InferTaint.inferSecretSource()); - callSinkB(source); - } - - // shallow version of callSinkDeep2Bad - void FN_callShallowSinkBad(Obj o) { - o.f = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(id2(o).f); - } - - public void callDeepSink3Bad() { - Obj source = propagate(InferTaint.inferSecretSource()); - callSinkC(source); - } - - public void callDeepSink4Bad() { - Obj source = propagate(InferTaint.inferSecretSource()); - callSinkD(source); - } - - public static void swapParams(Object o1, Object o2) { - o1 = o2; - } - - public static void assignSourceToParam(Object o) { - o = InferTaint.inferSecretSource(); - } - - public static void swapParamsOk() { - Object notASource = null; - Object source = InferTaint.inferSecretSource(); - swapParams(notASource, source); - InferTaint.inferSensitiveSink(notASource); - } - - public static void assignSourceToParamOk() { - Object o = null; - assignSourceToParam(o); - InferTaint.inferSensitiveSink(o); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/LoggingPrivateData.java b/infer/tests/codetoanalyze/java/quandary/LoggingPrivateData.java deleted file mode 100644 index 307c3309351..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/LoggingPrivateData.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import android.location.Location; -import android.telephony.TelephonyManager; -import android.util.Log; - -public class LoggingPrivateData { - - private native int rand(); - - public void logAllSourcesBad(Location l, TelephonyManager t) { - String source = null; - switch (rand()) { - case 1: - source = String.valueOf(l.getAltitude()); - break; - case 2: - source = String.valueOf(l.getBearing()); - break; - case 3: - source = String.valueOf(l.getLatitude()); - break; - case 4: - source = String.valueOf(l.getLongitude()); - break; - case 5: - source = String.valueOf(l.getSpeed()); - break; - case 6: - source = t.getDeviceId(); - break; - case 7: - source = t.getLine1Number(); - break; - case 8: - source = t.getSimSerialNumber(); - break; - case 9: - source = t.getSubscriberId(); - break; - case 10: - source = t.getVoiceMailNumber(); - break; - } - - String TAG = "tag"; - Log.e(TAG, source); - Log.println(0, TAG, source); - Log.w(TAG, source); - Log.wtf(TAG, source); // 10 sources * 4 sinks = 40 expected reports - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/Makefile b/infer/tests/codetoanalyze/java/quandary/Makefile deleted file mode 100644 index 0ded4e277d9..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) Facebook, Inc. and its affiliates. -# -# This source code is licensed under the MIT license found in the -# LICENSE file in the root directory of this source tree. - -TESTS_DIR = ../../.. - -INFER_OPTIONS = --quandary-only --quandary-show-passthroughs --debug-exceptions -INFERPRINT_OPTIONS = --issues-tests -TEST_CLASSPATH = $(JAVA_BUILTINS_DIR) -SOURCES = $(wildcard *.java) - -include $(TESTS_DIR)/javac.make diff --git a/infer/tests/codetoanalyze/java/quandary/Recursion.java b/infer/tests/codetoanalyze/java/quandary/Recursion.java deleted file mode 100644 index 1117a0fa566..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/Recursion.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import com.facebook.infer.builtins.InferTaint; - -public class Recursion { - - public static void divergeOk() { - divergeOk(); - } - - public static void callSinkThenDiverge(Object param) { - InferTaint.inferSensitiveSink(param); - callSinkThenDiverge(param); - } - - public static void callSinkThenDivergeBad() { - callSinkThenDiverge(InferTaint.inferSecretSource()); - } - - public static void safeRecursionCallSink(int i, Object param) { - if (i == 0) return; - InferTaint.inferSensitiveSink(param); - safeRecursionCallSink(i - 1, param); - } - - public static void safeRecursionCallSinkBad() { - safeRecursionCallSink(5, InferTaint.inferSecretSource()); - } - - // TODO (#16595757): Requires support for recursion in Ondemand - public static void FN_recursionBad(int i, Object param) { - if (i == 0) return; - InferTaint.inferSensitiveSink(param); - FN_recursionBad(i - 1, InferTaint.inferSecretSource()); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/Serialization.java b/infer/tests/codetoanalyze/java/quandary/Serialization.java deleted file mode 100644 index 3335a861550..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/Serialization.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import com.facebook.infer.builtins.InferTaint; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; - -public class Serialization { - - // we could warn on only particular calls to the tainted ObjectInputStream (e.g., readObject, - // readUnshared, but nothing good can come from creating a tainted ObjectInputStream - Object taintedObjectInputStreamBad() throws IOException, ClassNotFoundException { - Object source = InferTaint.inferSecretSource(); - ObjectInputStream stream = new ObjectInputStream((InputStream) source); // report here - return stream.readObject(); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/Services.java b/infer/tests/codetoanalyze/java/quandary/Services.java deleted file mode 100644 index 77665f48e2b..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/Services.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import java.io.IOException; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.sql.SQLException; -import java.sql.Statement; - -class Services {} - -@Retention(RetentionPolicy.CLASS) -@interface ThriftService {} - -@ThriftService -interface GeneratedServiceInterface { - public void serviceMethodBad(String s) throws IOException; - - public void paramToSql1Bad(String s) throws SQLException; - - public void paramToSql2Bad(String s) throws SQLException; - - public void paramToSql3Bad(String s) throws SQLException; - - public void paramToSql4Bad(String s) throws SQLException; - - public void paramToSql5Bad(String s) throws SQLException; - - void packageProtectedServiceMethodBad(String s) throws IOException; -} - -class Service1 implements GeneratedServiceInterface { - - @Override - public void serviceMethodBad(String s) throws IOException { - Runtime.getRuntime().exec(s); // RCE if s is tainted, we should warn - } - - Statement mStatement; - - @Override - public void paramToSql1Bad(String s) throws SQLException { - mStatement.execute(s); - } - - @Override - public void paramToSql2Bad(String s) throws SQLException { - mStatement.executeLargeUpdate(s); - } - - @Override - public void paramToSql3Bad(String s) throws SQLException { - mStatement.executeQuery(s); - } - - @Override - public void paramToSql4Bad(String s) throws SQLException { - mStatement.executeUpdate(s); - } - - @Override - public void paramToSql5Bad(String s) throws SQLException { - mStatement.addBatch(s); - mStatement.executeBatch(); - } - - @Override - public void packageProtectedServiceMethodBad(String s) throws IOException { - Runtime.getRuntime().exec(s); - } - - // doesn't override a method from the service interface; not an endpoint - public void publicMethodNotEndpointOk(String s) throws IOException { - Runtime.getRuntime().exec(s); - } - - // same - protected void protectedMethodNotEndpointOk(String s) throws IOException { - Runtime.getRuntime().exec(s); - } - - void packageProtectedMethodNotEndpointOk(String s) throws IOException { - Runtime.getRuntime().exec(s); - } - - // same - private void privateMethodNotEndpointOk(String s) throws IOException { - Runtime.getRuntime().exec(s); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/Strings.java b/infer/tests/codetoanalyze/java/quandary/Strings.java deleted file mode 100644 index 892f6267cd9..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/Strings.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -// package codetoanalyze.java.quandary; - -import com.facebook.infer.builtins.InferTaint; -import java.util.Formatter; - -/** - * a lot of tainted values are strings, so propagation through StringBuilder's and the like is very - * important. - */ -public class Strings { - - void viaStringBuilderSugarBad() { - Object source = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(source + ""); - } - - void viaStringBuilderBad() { - Object source = InferTaint.inferSecretSource(); - StringBuilder builder = new StringBuilder(); - InferTaint.inferSensitiveSink(builder.append(source).append("").toString()); - } - - void viaStringBuilderIgnoreReturnBad() { - Object source = InferTaint.inferSecretSource(); - StringBuilder builder = new StringBuilder(); - // builder should be tainted after this call even though we ignore the return value - builder.append(source); - InferTaint.inferSensitiveSink(builder.toString()); - } - - void viaStringBufferBad() { - Object source = InferTaint.inferSecretSource(); - StringBuffer buffer = new StringBuffer(); - InferTaint.inferSensitiveSink(buffer.append("").append(source).toString()); - } - - void viaStringBufferIgnoreReturnBad() { - Object source = InferTaint.inferSecretSource(); - StringBuffer buffer = new StringBuffer(); - buffer.append(source); - InferTaint.inferSensitiveSink(buffer.toString()); - } - - void viaFormatterBad() { - Object source = InferTaint.inferSecretSource(); - Formatter formatter = new Formatter(); - InferTaint.inferSensitiveSink(formatter.format("%s", source).toString()); - } - - void viaFormatterIgnoreReturnBad() { - Object source = InferTaint.inferSecretSource(); - Formatter formatter = new Formatter(); - formatter.format("%s", source); - InferTaint.inferSensitiveSink(formatter.toString()); - } - - void viaStringFormatVarArgsDirectBad() { - Object source = InferTaint.inferSecretSource(); - String tainted = String.format("%s%s", "hi", source); - InferTaint.inferSensitiveSink(tainted); - } - - void viaStringFormatVarArgsIndirect(Object param) { - String tainted = String.format("%s%s", "hi", param); - InferTaint.inferSensitiveSink(tainted); - } - - void viaStringFormatVarArgsIndirectBad() { - viaStringFormatVarArgsIndirect(InferTaint.inferSecretSource()); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/TaintExample.java b/infer/tests/codetoanalyze/java/quandary/TaintExample.java deleted file mode 100644 index 3537c2e74ae..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/TaintExample.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import android.content.ContentValues; -import android.content.SharedPreferences; -import com.facebook.infer.annotation.IntegritySink; -import com.facebook.infer.annotation.IntegritySource; -import com.facebook.infer.annotation.PrivacySink; -import com.facebook.infer.annotation.PrivacySource; -import com.facebook.infer.builtins.InferTaint; -import java.io.IOException; -import java.io.InputStream; -import java.net.Socket; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLException; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; - -public class TaintExample { - - public InputStream socketNotVerifiedSimple_FN(SSLSocketFactory f) throws IOException { - Socket socket = f.createSocket(); - return socket.getInputStream(); - } - - public InputStream socketVerifiedForgotToCheckRetval_FN( - SSLSocketFactory f, HostnameVerifier v, SSLSession session) throws IOException { - - Socket socket = f.createSocket(); - v.verify("hostname", session); - return socket.getInputStream(); - } - - public InputStream socketVerifiedOk1(SSLSocketFactory f, HostnameVerifier v, SSLSession session) - throws IOException { - - Socket socket = f.createSocket(); - if (v.verify("hostname", session)) { - return socket.getInputStream(); - } else { - return null; - } - } - - HostnameVerifier mHostnameVerifier; - - public void throwExceptionIfNoVerify(SSLSocket sslSocket, String host) throws IOException { - - if (!mHostnameVerifier.verify(host, sslSocket.getSession())) { - throw new SSLException("Couldn't verify!"); - } - } - - public InputStream socketVerifiedOk2(SSLSocketFactory f) throws IOException { - SSLSocket s = (SSLSocket) f.createSocket(); - throwExceptionIfNoVerify(s, "hostname"); - return s.getInputStream(); - } - - public InputStream socketIgnoreExceptionNoVerify_FN(SSLSocketFactory f) throws IOException { - - SSLSocket s = (SSLSocket) f.createSocket(); - try { - throwExceptionIfNoVerify(s, "hostname"); - } catch (SSLException e) { - // ignore the fact that verifying the socket failed - } - return s.getInputStream(); - } - - public InputStream taintingShouldNotPreventInference1_FN(SSLSocketFactory f) throws IOException { - socketNotVerifiedSimple_FN(f).toString(); - // failing to infer a post for socketNotVerifiedSimple will hide this error - Socket s = f.createSocket(); - return s.getInputStream(); - } - - public InputStream readInputStream(Socket socket) throws IOException { - return socket.getInputStream(); - } - - // if we're not careful, postcondition inference will fail for this function - Socket callReadInputStreamCauseTaintError_FN(SSLSocketFactory f) throws IOException { - Socket socket = f.createSocket(); - InputStream s = readInputStream(socket); - s.toString(); // to avoid RETURN_VALUE_IGNORED warning - return f.createSocket(); - } - - InputStream taintingShouldNotPreventInference2(SSLSocketFactory f) throws IOException { - // if inference fails for this callee, we won't report an error here - Socket s = callReadInputStreamCauseTaintError_FN(f); - return s.getInputStream(); - } - - public void simpleTaintErrorWithModelMethods() { - Object o = InferTaint.inferSecretSource(); - InferTaint.inferSensitiveSink(o); - } - - public Object returnTaintedSourceModelMethods() { - return InferTaint.inferSecretSource(); - } - - public void callSinkMethodModelMethods(Object o) { - InferTaint.inferSensitiveSink(o); - } - - public void interprocTaintErrorWithModelMethods1() { - InferTaint.inferSensitiveSink(returnTaintedSourceModelMethods()); - } - - public void interprocTaintErrorWithModelMethods2() { - callSinkMethodModelMethods(InferTaint.inferSecretSource()); - } - - public void interprocTaintErrorWithModelMethods3() { - callSinkMethodModelMethods(returnTaintedSourceModelMethods()); - } - - public void simpleTaintErrorWithModelMethodsUndefined_FN() { - Object o = InferTaint.inferSecretSourceUndefined(); - InferTaint.inferSensitiveSinkUndefined(o); - } - - public Object returnTaintedSourceModelMethodsUndefined() { - return InferTaint.inferSecretSourceUndefined(); - } - - public void callSinkMethodModelMethodsUndefined(Object o) { - InferTaint.inferSensitiveSinkUndefined(o); - } - - public void interprocTaintErrorWithModelMethodsUndefined1_FN() { - InferTaint.inferSensitiveSinkUndefined(returnTaintedSourceModelMethodsUndefined()); - } - - public void interprocTaintErrorWithModelMethodsUndefined2_FN() { - callSinkMethodModelMethodsUndefined(InferTaint.inferSecretSourceUndefined()); - } - - public void interprocTaintErrorWithModelMethodsUndefined3_FN() { - callSinkMethodModelMethodsUndefined(returnTaintedSourceModelMethodsUndefined()); - } - - public void contentValuesPutWithTaintedString_FN( - ContentValues values, SharedPreferences prefs, String key, String value) { - values.put(key, prefs.getString(key, value)); - } - - public void contentValuesPutOk(ContentValues values, String key, String value) { - values.put(key, value); - } - - @PrivacySource - public String privacySource() { - return "source"; - } - - public void testPrivacySourceAnnot_FN() { - InferTaint.inferSensitiveSinkUndefined(privacySource()); // should report - } - - public void instancePrivacySink(@PrivacySink String s1, String s2) {} - - public static void staticPrivacySink(@PrivacySink String s1, String s2) {} - - public void testPrivacySinkAnnot1_FN() { - String source = privacySource(); - instancePrivacySink(source, ""); // should report - } - - public void testPrivacySinkAnnot2() { - String source = privacySource(); - instancePrivacySink("", source); // should not report - } - - public void testPrivacySinkAnnot3_FN() { - String source = privacySource(); - staticPrivacySink(source, ""); // should report - } - - public void testPrivacySinkAnnot4() { - String source = privacySource(); - staticPrivacySink("", source); // should not report - } - - @PrivacySource String mPrivacySource; - - @PrivacySource String sPrivacySource; - - public void testPrivacySourceInstanceFieldAnnot_FN() { - String source = mPrivacySource; - InferTaint.inferSensitiveSinkUndefined(source); // should report - } - - public void testPrivacySourceStaticFieldAnnot_FN() { - String source = sPrivacySource; - InferTaint.inferSensitiveSinkUndefined(source); // should report - } - - String aFieldWithoutAnnotations; - - public void testPrivacySourceFieldAnnotPropagation_FN() { - aFieldWithoutAnnotations = mPrivacySource; - InferTaint.inferSensitiveSinkUndefined(aFieldWithoutAnnotations); // should report - } - - @IntegritySource - public String integritySource() { - return "source"; - } - - @IntegritySource String mIntegritySource; - - @IntegritySource String sIntegritySource; - - public void testIntegritySourceAnnot_FN() { - InferTaint.inferSensitiveSinkUndefined(integritySource()); // should report - } - - public void testIntegritySourceInstanceFieldAnnot_FN() { - String source = mIntegritySource; - InferTaint.inferSensitiveSinkUndefined(source); // should report - } - - public void testIntegritySourceStaticFieldAnnot_FN() { - String source = sIntegritySource; - InferTaint.inferSensitiveSinkUndefined(source); // should report - } - - public void integritySink(@IntegritySink String s1, String s2) {} - - void testIntegritySinkAnnotReport_FN(String s) { - integritySink(integritySource(), s); // should report - } - - void testIntegritySinkAnnotNoReport(String s) { - integritySink(s, integritySource()); // should not report - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/TaintedFormals.java b/infer/tests/codetoanalyze/java/quandary/TaintedFormals.java deleted file mode 100644 index b237a50fee5..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/TaintedFormals.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import android.app.Activity; -import android.content.Intent; -import com.facebook.infer.builtins.InferTaint; - -class Obj { - Object f; -} - -public class TaintedFormals { - - public Activity mActivity; - - public void callSink(Object formal) { - InferTaint.inferSensitiveSink(formal); - } - - // taintedFormal1 and taintedFormal2 were are modeled as tainted - public void taintedContextBad( - String taintedFormal1, Intent untaintedFormal, Integer taintedFormal2) { - InferTaint.inferSensitiveSink(taintedFormal1); // should report here - InferTaint.inferSensitiveSink(taintedFormal2); // should report here - callSink(taintedFormal1); // should report here - callSink(taintedFormal2); // should report here - - // using different sink to avoid confusion with the above - mActivity.startService(untaintedFormal); // should not report here - } - - public Object taintedContextBad(String taintedFormal) { - return taintedFormal; - } - - public void callTaintedContextBad1(String formal) { - Object tainted = taintedContextBad(formal); - InferTaint.inferSensitiveSink(tainted); - } - - public void callTaintedContextBad2() { - taintedContextBad(null, (Intent) InferTaint.inferSecretSource(), null); - } - - public void callTaintedContextOk1() { - taintedContextBad("foo", null, null); - } - - // shouldn't report here, otherwise we will double report - public void callTaintedContextOk2() { - taintedContextBad(null, null, new Integer(1)); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/Traces.java b/infer/tests/codetoanalyze/java/quandary/Traces.java deleted file mode 100644 index ebb8e675f00..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/Traces.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import com.facebook.infer.builtins.InferTaint; - -class Traces { - void sourceMethod() { - Obj source = (Obj) InferTaint.inferSecretSource(); - callSameSink(null, source, null, null); - } - - void callSameSink(Obj o1, Obj o2, Obj o3, Obj o4) { - callMySink(o1); - callMySinkIndirect(o2); // test that we expand this sink in the trace - callMySink(o3); - callMySink(o4); - } - - void callMySinkIndirect(Obj o) { - callMySink(o); - } - - void callMySink(Obj o) { - InferTaint.inferSensitiveSink(o); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/UnknownCode.java b/infer/tests/codetoanalyze/java/quandary/UnknownCode.java deleted file mode 100644 index e159f00c4f8..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/UnknownCode.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import android.content.Intent; -import android.os.Parcel; -import com.facebook.infer.builtins.InferTaint; - -/** testing how the analysis handles missing/unknown code */ -public abstract class UnknownCode { - - static native Object nativeMethod(Object o); - - abstract Object abstractMethod(Object o); - - static interface Interface { - Object interfaceMethod(Object o); - } - - static void propagateViaUnknownConstructorBad() { - String source = (String) InferTaint.inferSecretSource(); - // we don't analyze the code for the core Java libraries, so this constructor will be unknown - String unknownConstructor = new String(source); - InferTaint.inferSensitiveSink(unknownConstructor); - } - - static void propagateViaUnknownConstructorOk() { - String unknownConstructor = new String(""); - InferTaint.inferSensitiveSink(unknownConstructor); - } - - void propagateViaUnknownCodeOk(Interface i) { - Object notASource = new Object(); - Object launderedSource1 = nativeMethod(notASource); - Object launderedSource2 = abstractMethod(launderedSource1); - Object launderedSource3 = i.interfaceMethod(launderedSource2); - InferTaint.inferSensitiveSink(launderedSource3); - } - - void callUnknownSetterBad(Intent i) { - Object source = InferTaint.inferSecretSource(); - // we don't analyze the source code for Android, so this will be unknown - i.writeToParcel((Parcel) source, 0); - InferTaint.inferSensitiveSink(i); - } - - void propagateEmptyBad() { - String source = (String) InferTaint.inferSecretSource(); - StringBuffer buffer = new StringBuffer(); - buffer.append(source); // buffer is now tainted - // even though "" is not tainted, buffer and alias should still be tainted - StringBuffer alias = buffer.append(""); - InferTaint.inferSensitiveSink(buffer); // should report - InferTaint.inferSensitiveSink(alias); // should report - } - - void propagateFootprint(String param) { - StringBuffer buffer = new StringBuffer(); - buffer.append(param); - InferTaint.inferSensitiveSink(buffer); - } - - void callPropagateFootprintBad() { - propagateFootprint((String) InferTaint.inferSecretSource()); - } - - static void propagateViaInterfaceCodeBad(Interface i) { - Object source = InferTaint.inferSecretSource(); - Object launderedSource = i.interfaceMethod(source); - InferTaint.inferSensitiveSink(launderedSource); - } - - void propagateViaUnknownNativeCodeBad() { - Object source = InferTaint.inferSecretSource(); - Object launderedSource = nativeMethod(source); - InferTaint.inferSensitiveSink(launderedSource); - } - - static void propagateViaUnknownAbstractCodeBad() { - Object source = InferTaint.inferSecretSource(); - Object launderedSource = nativeMethod(source); - InferTaint.inferSensitiveSink(launderedSource); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/UserControlledStrings.java b/infer/tests/codetoanalyze/java/quandary/UserControlledStrings.java deleted file mode 100644 index 2dd90159a9b..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/UserControlledStrings.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import android.content.ClipboardManager; -import android.text.Html; -import android.text.Spanned; -import android.widget.EditText; -import com.facebook.infer.builtins.InferTaint; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -public class UserControlledStrings { - ClipboardManager clipboard; - - void readClipboardSourcesBad() { - InferTaint.inferSensitiveSink(clipboard.getText()); - InferTaint.inferSensitiveSink(clipboard.getPrimaryClip()); - InferTaint.inferSensitiveSink(clipboard.getPrimaryClip().getItemAt(5)); - InferTaint.inferSensitiveSink(clipboard.getPrimaryClip().getItemAt(5).getText()); - InferTaint.inferSensitiveSink(clipboard.getPrimaryClip().toString()); - // 5 reports - } - - Spanned clipboardToHtmlBad() { - return Html.fromHtml(clipboard.getText().toString()); - } - - EditText mEditText; - - Spanned editTextToHtmlBad() { - return Html.fromHtml(mEditText.getText().toString()); - } - - void clipboardToShellDirectBad() throws IOException { - Runtime.getRuntime().exec(clipboard.getText().toString()); - } - - void clipboardToShellArrayBad() throws IOException { - String[] cmds = new String[] {"ls", clipboard.getText().toString()}; - Runtime.getRuntime().exec(cmds); - } - - ProcessBuilder clipboardToProcessBuilder1Bad() { - return new ProcessBuilder(clipboard.getText().toString()); - } - - ProcessBuilder clipboardToProcessBuilder2Bad() { - return new ProcessBuilder("sh", clipboard.getText().toString()); - } - - ProcessBuilder clipboardToProcessBuilder3Bad(ProcessBuilder builder) { - return builder.command(clipboard.getText().toString()); - } - - ProcessBuilder clipboardToProcessBuilder4Bad(ProcessBuilder builder) { - List cmds = new ArrayList(); - cmds.add(clipboard.getText().toString()); - return builder.command(cmds); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/WebViews.java b/infer/tests/codetoanalyze/java/quandary/WebViews.java deleted file mode 100644 index 36f63f03ed8..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/WebViews.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package codetoanalyze.java.quandary; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.webkit.JavascriptInterface; -import android.webkit.JsPromptResult; -import android.webkit.JsResult; -import android.webkit.WebChromeClient; -import android.webkit.WebResourceRequest; -import android.webkit.WebResourceResponse; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import com.facebook.infer.builtins.InferTaint; -import java.io.File; -import java.net.URISyntaxException; - -public class WebViews { - - void callWebviewSinks(WebView webview) { - String stringSource = (String) InferTaint.inferSecretSource(); - - webview.evaluateJavascript(stringSource, null); - webview.loadData(stringSource, "", ""); - webview.loadDataWithBaseURL("", stringSource, "", "", ""); - webview.loadUrl(stringSource); // should have 5 reports - webview.postUrl(stringSource, null); - webview.postWebMessage(null, (Uri) InferTaint.inferSecretSource()); - } - - // make sure all of the rules apply to subclasses as well - class MyWebView extends WebView { - public MyWebView(Context c) { - super(c); - } - } - - Activity mActivity; - - class MyWebViewClient extends WebViewClient { - - @Override - public void onLoadResource(WebView w, String url) { - try { - Intent i = Intent.parseUri(url, 0); - mActivity.startActivity(i); // should report - } catch (URISyntaxException e) { - } - } - - @Override - public WebResourceResponse shouldInterceptRequest(WebView w, WebResourceRequest request) { - mActivity.startActivity(new Intent("action", request.getUrl())); // should report - return null; - } - - File webResourceToFileBad(WebResourceRequest request) { - return new File(request.getUrl().getPath()); - } - - @Override - public boolean shouldOverrideUrlLoading(WebView w, String url) { - try { - Intent i = Intent.parseUri(url, 0); - mActivity.startActivity(i); // should report - } catch (URISyntaxException e) { - } - return false; - } - } - - class MyWebChromeClient extends WebChromeClient { - - @Override - public boolean onJsAlert(WebView w, String url, String message, JsResult result) { - try { - Intent i = Intent.parseUri(url, 0); - mActivity.startActivity(i); - } catch (URISyntaxException e) { - } - return false; - } - - @Override - public boolean onJsBeforeUnload(WebView w, String url, String m, JsResult result) { - try { - Intent i = Intent.parseUri(url, 0); - mActivity.startActivity(i); - } catch (URISyntaxException e) { - } - return false; - } - - @Override - public boolean onJsConfirm(WebView w, String url, String m, JsResult result) { - try { - Intent i = Intent.parseUri(url, 0); - mActivity.startActivity(i); - } catch (URISyntaxException e) { - } - return false; - } - - @Override - public boolean onJsPrompt(WebView w, String url, String m, String s, JsPromptResult result) { - try { - Intent i = Intent.parseUri(url, 0); - mActivity.startActivity(i); - } catch (URISyntaxException e) { - } - return false; - } - } - - void callWebviewSubclassSink(MyWebView webview) { - String stringSource = (String) InferTaint.inferSecretSource(); - webview.evaluateJavascript(stringSource, null); - } - - class JsObject { - @JavascriptInterface - Object returnSource() { - return InferTaint.inferSecretSource(); - } - } - - // in order to get this, we have to understand that addJavaScriptInterface can evaluate the - // JsObject.returnSource method - void FN_addJavascriptInterface(MyWebView webview) { - // should warn here - webview.addJavascriptInterface(new JsObject(), "injectedObject"); - } -} diff --git a/infer/tests/codetoanalyze/java/quandary/issues.exp b/infer/tests/codetoanalyze/java/quandary/issues.exp deleted file mode 100644 index 8fafa93b3f0..00000000000 --- a/infer/tests/codetoanalyze/java/quandary/issues.exp +++ /dev/null @@ -1,254 +0,0 @@ -codetoanalyze/java/quandary/Arrays.java, codetoanalyze.java.quandary.Arrays.viaArrayBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Arrays.java, codetoanalyze.java.quandary.Arrays.viaArrayThenFieldBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Arrays.java, codetoanalyze.java.quandary.Arrays.viaFieldThenArrayBad1(codetoanalyze.java.quandary.Arrays$Obj):void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Arrays.java, codetoanalyze.java.quandary.Arrays.viaFieldThenArrayBad2():void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Arrays.java, codetoanalyze.java.quandary.Arrays.FP_viaArrayOk1(java.lang.Object,java.lang.Object[]):void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Arrays.java, codetoanalyze.java.quandary.Arrays.FP_viaArrayOk2(java.lang.Object,java.lang.Object[]):void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.directBad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.viaVarBad1():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.viaVarBad2():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.viaVarBad3():void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.viaCastBad1():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.viaCastBad2():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.ifBad1(boolean):void, 5, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.ifBad2(boolean):void, 5, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.ifBad3(boolean):void, 7, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.ifBad4(boolean,boolean):void, 9, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.ifBad5(boolean):void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.switchBad1(int):void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.switchBad2(int):void, 6, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.switchBad3(int):void, 7, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.whileBad1(int):void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.whileBad2(int):void, 6, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.noTripleReportBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.noTripleReportBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.arrayWithTaintedContentsBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.funCallBad1():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Basics.funCallBad2(int,Object) with tainted index 2,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.FP_deadCodeOk():void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Basics.java, codetoanalyze.java.quandary.Basics.FP_loopInvariantOk():void, 5, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/ClassLoading.java, codetoanalyze.java.quandary.ClassLoading.clipboardToClassForNameBad():void, 2, SHELL_INJECTION, no_bucket, ERROR, [Return from CharSequence ClipboardManager.getText() with tainted data return*,Return from String ClassLoading.getUserControlledString(),Call to Class Class.forName(String) with tainted index 0] -codetoanalyze/java/quandary/ContentProviders.java, codetoanalyze.java.quandary.ContentProviders.bulkInsert(android.net.Uri,android.content.ContentValues[]):int, 1, UNTRUSTED_FILE, no_bucket, ERROR, [Return from int ContentProviders.bulkInsert(Uri,ContentValues[]),Call to File.(String) with tainted index 1] -codetoanalyze/java/quandary/ContentProviders.java, codetoanalyze.java.quandary.ContentProviders.call(java.lang.String,java.lang.String,android.os.Bundle):android.os.Bundle, 1, UNTRUSTED_FILE, no_bucket, ERROR, [Return from Bundle ContentProviders.call(String,String,Bundle),Call to File.(String) with tainted index 1] -codetoanalyze/java/quandary/ContentProviders.java, codetoanalyze.java.quandary.ContentProviders.delete(android.net.Uri,java.lang.String,java.lang.String[]):int, 1, UNTRUSTED_FILE, no_bucket, ERROR, [Return from int ContentProviders.delete(Uri,String,String[]),Call to File.(String) with tainted index 1] -codetoanalyze/java/quandary/ContentProviders.java, codetoanalyze.java.quandary.ContentProviders.insert(android.net.Uri,android.content.ContentValues):android.net.Uri, 1, UNTRUSTED_FILE, no_bucket, ERROR, [Return from Uri ContentProviders.insert(Uri,ContentValues),Call to File.(String) with tainted index 1] -codetoanalyze/java/quandary/ContentProviders.java, codetoanalyze.java.quandary.ContentProviders.getType(android.net.Uri):java.lang.String, 1, UNTRUSTED_FILE, no_bucket, ERROR, [Return from String ContentProviders.getType(Uri),Call to File.(String) with tainted index 1] -codetoanalyze/java/quandary/ContentProviders.java, codetoanalyze.java.quandary.ContentProviders.openAssetFile(android.net.Uri,java.lang.String,android.os.CancellationSignal):android.content.res.AssetFileDescriptor, 1, UNTRUSTED_FILE, no_bucket, ERROR, [Return from AssetFileDescriptor ContentProviders.openAssetFile(Uri,String,CancellationSignal),Call to File.(String) with tainted index 1] -codetoanalyze/java/quandary/ContentProviders.java, codetoanalyze.java.quandary.ContentProviders.openFile(android.net.Uri,java.lang.String,android.os.CancellationSignal):android.os.ParcelFileDescriptor, 1, UNTRUSTED_FILE, no_bucket, ERROR, [Return from ParcelFileDescriptor ContentProviders.openFile(Uri,String,CancellationSignal),Call to File.(String) with tainted index 1] -codetoanalyze/java/quandary/ContentProviders.java, codetoanalyze.java.quandary.ContentProviders.openTypedAssetFile(android.net.Uri,java.lang.String,android.os.Bundle,android.os.CancellationSignal):android.content.res.AssetFileDescriptor, 2, UNTRUSTED_FILE, no_bucket, ERROR, [Return from AssetFileDescriptor ContentProviders.openTypedAssetFile(Uri,String,Bundle,CancellationSignal),Call to File.(String) with tainted index 1] -codetoanalyze/java/quandary/ContentProviders.java, codetoanalyze.java.quandary.ContentProviders.query(android.net.Uri,java.lang.String[],java.lang.String,java.lang.String[],java.lang.String):android.database.Cursor, 2, UNTRUSTED_FILE, no_bucket, ERROR, [Return from Cursor ContentProviders.query(Uri,String[],String,String[],String),Call to File.(String) with tainted index 1] -codetoanalyze/java/quandary/ContentProviders.java, codetoanalyze.java.quandary.ContentProviders.update(android.net.Uri,android.content.ContentValues,java.lang.String,java.lang.String[]):int, 1, UNTRUSTED_FILE, no_bucket, ERROR, [Return from int ContentProviders.update(Uri,ContentValues,String,String[]),Call to File.(String) with tainted index 1] -codetoanalyze/java/quandary/DynamicDispatch.java, codetoanalyze.java.quandary.DynamicDispatch.propagateViaInterfaceBad(codetoanalyze.java.quandary.DynamicDispatch$Interface):void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Exceptions.java, codetoanalyze.java.quandary.Exceptions.sinkInCatchBad1():void, 5, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Exceptions.java, codetoanalyze.java.quandary.Exceptions.sinkInCatchBad2():void, 6, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Exceptions.java, codetoanalyze.java.quandary.Exceptions.sinkAfterCatchBad():void, 7, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Exceptions.java, codetoanalyze.java.quandary.Exceptions.sinkInFinallyBad1():void, 5, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Exceptions.java, codetoanalyze.java.quandary.Exceptions.sinkInFinallyBad2():void, 6, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Exceptions.java, codetoanalyze.java.quandary.Exceptions.sinkInFinallyBad3():void, 7, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Exceptions.java, codetoanalyze.java.quandary.Exceptions.callSinkThenThrowBad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Exceptions.callSinkThenThrow(Object) with tainted index 0,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/ExternalSpecs.java, codetoanalyze.java.quandary.ExternalSpecs.logExternalSourceBad():void, 1, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from Object ExternalSpecs.privateDataSource(),Call to int Log.e(String,String) with tainted index 1] -codetoanalyze/java/quandary/ExternalSpecs.java, codetoanalyze.java.quandary.ExternalSpecs.callExternalSinkBad():void, 1, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from Object ExternalSpecs.privateDataSource(),Call to void ExternalSpecs.loggingSink1(Object,Object) with tainted index 1] -codetoanalyze/java/quandary/ExternalSpecs.java, codetoanalyze.java.quandary.ExternalSpecs.callExternalSink2Bad1():void, 1, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from Object ExternalSpecs.privateDataSource(),Call to void ExternalSpecs.loggingSink2(Object,Object) with tainted index 0] -codetoanalyze/java/quandary/ExternalSpecs.java, codetoanalyze.java.quandary.ExternalSpecs.callExternalSink2Bad2():void, 1, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from Object ExternalSpecs.privateDataSource(),Call to void ExternalSpecs.loggingSink2(Object,Object) with tainted index 1] -codetoanalyze/java/quandary/ExternalSpecs.java, codetoanalyze.java.quandary.ExternalSpecs.missedSanitizerBad():java.lang.Object, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/ExternalSpecs.java, codetoanalyze.java.quandary.ExternalSpecs.callSinkThatPropagatesBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Object ExternalSpecs.sinkThatPropagates(Object) with tainted index 0] -codetoanalyze/java/quandary/ExternalSpecs.java, codetoanalyze.java.quandary.ExternalSpecs.callSinkThatPropagatesBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void ExternalSpecs.loggingSink1(Object,Object) with tainted index 1] -codetoanalyze/java/quandary/ExternalSpecs.java, codetoanalyze.java.quandary.InterfaceSpecImpl.externalSpecBad():void, 1, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from Object InterfaceSpecImpl.source(),Call to void InterfaceSpecImpl.sink(Object) with tainted index 1] -codetoanalyze/java/quandary/ExternalSpecs.java, codetoanalyze.java.quandary.InterfaceSpecImpl.externalSpecBad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InterfaceSpecImpl.source(),Call to void InterfaceSpecImpl.sink(Object) with tainted index 1] -codetoanalyze/java/quandary/ExternalSpecs.java, codetoanalyze.java.quandary.ConstructorSink.constructorSinkBad():codetoanalyze.java.quandary.ConstructorSink, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to ConstructorSink.(Object) with tainted index 1] -codetoanalyze/java/quandary/Fields.java, codetoanalyze.java.quandary.Fields.instanceFieldBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Fields.java, codetoanalyze.java.quandary.Fields.staticFieldBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Fields.java, codetoanalyze.java.quandary.Fields.viaFieldBad1(codetoanalyze.java.quandary.Fields$Obj):void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Fields.java, codetoanalyze.java.quandary.Fields.viaFieldBad2():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Fields.java, codetoanalyze.java.quandary.Fields.viaFieldBad3():void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Fields.java, codetoanalyze.java.quandary.Fields.viaNestedFieldBad1(codetoanalyze.java.quandary.Fields$Obj):void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Fields.java, codetoanalyze.java.quandary.Fields.viaNestedFieldBad2():void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Files.java, codetoanalyze.java.quandary.Files.fileConstructorSinkBad():java.io.File, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to File.(String) with tainted index 1] -codetoanalyze/java/quandary/Files.java, codetoanalyze.java.quandary.Files.fileSystemConstructorSinkBad1():java.nio.file.Path, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Path FileSystem.getPath(String,String[]) with tainted index 1] -codetoanalyze/java/quandary/Files.java, codetoanalyze.java.quandary.Files.fileSystemConstructorSinkBad2():java.nio.file.Path, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Path FileSystem.getPath(String,String[]) with tainted index 2] -codetoanalyze/java/quandary/Files.java, codetoanalyze.java.quandary.Files.pathsSinkBad1():java.nio.file.Path, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Path Paths.get(String,String[]) with tainted index 0] -codetoanalyze/java/quandary/Files.java, codetoanalyze.java.quandary.Files.pathsSinkBad2():java.nio.file.Path, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Path Paths.get(String,String[]) with tainted index 1] -codetoanalyze/java/quandary/FlowSensitivity.java, codetoanalyze.java.quandary.FlowSensitivity.interproceduralFlowSensitivityBad(codetoanalyze.java.quandary.FlowSensitivity$Obj):void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data @val$0.f*,Return from void FlowSensitivity.returnSource(FlowSensitivity$Obj),Call to void FlowSensitivity.callSink(FlowSensitivity$Obj) with tainted index 0,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/FlowSensitivity.java, codetoanalyze.java.quandary.FlowSensitivity.callSourceAndSinkBad1(codetoanalyze.java.quandary.FlowSensitivity$Obj):void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data @val$0.f*,Return from void FlowSensitivity.sourceAndSink(FlowSensitivity$Obj),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/FlowSensitivity.java, codetoanalyze.java.quandary.FlowSensitivity.callSourceAndSinkBad2(codetoanalyze.java.quandary.FlowSensitivity$Obj):void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void FlowSensitivity.sourceAndSink(FlowSensitivity$Obj) with tainted index 0,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.MyActivity.startServiceWithTaintedIntent():void, 2, CREATE_INTENT_FROM_URI, no_bucket, ERROR, [Return from Intent.(String,Uri),Call to ComponentName ContextWrapper.startService(Intent) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to boolean ContextWrapper.bindService(Intent,ServiceConnection,int) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 5, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void ContextWrapper.sendBroadcast(Intent) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 6, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void ContextWrapper.sendBroadcastAsUser(Intent,UserHandle) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 7, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void ContextWrapper.sendOrderedBroadcast(Intent,String) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 8, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void ContextWrapper.sendOrderedBroadcastAsUser(Intent,UserHandle,String,BroadcastReceiver,Handler,int,String,Bundle) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 9, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void ContextWrapper.sendStickyBroadcast(Intent) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 10, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void ContextWrapper.sendStickyBroadcastAsUser(Intent,UserHandle) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 11, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void ContextWrapper.sendStickyOrderedBroadcast(Intent,BroadcastReceiver,Handler,int,String,Bundle) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 12, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void ContextWrapper.sendStickyOrderedBroadcastAsUser(Intent,UserHandle,BroadcastReceiver,Handler,int,String,Bundle) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 13, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Activity.startActivities(Intent[]) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 14, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Activity.startActivity(Intent) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 15, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Activity.startActivityForResult(Intent,int) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 16, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to boolean Activity.startActivityIfNeeded(Intent,int) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 17, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Activity.startActivityFromChild(Activity,Intent,int) with tainted index 2] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 18, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Activity.startActivityFromFragment(Fragment,Intent,int) with tainted index 2] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 19, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Activity.startIntentSender(IntentSender,Intent,int,int,int) with tainted index 2] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 20, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Activity.startIntentSenderForResult(IntentSender,int,Intent,int,int,int) with tainted index 3] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 21, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Activity.startIntentSenderFromChild(Activity,IntentSender,int,Intent,int,int,int) with tainted index 4] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 22, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to ComponentName ContextWrapper.startService(Intent) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllActivitySinksBad(android.app.Activity,java.lang.String):void, 23, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to boolean ContextWrapper.stopService(Intent) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllIntentSinks():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Intent Intent.parseUri(String,int) with tainted index 0] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllIntentSinks():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Intent Intent.getIntent(String) with tainted index 0] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllIntentSinks():void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Intent Intent.getIntentOld(String) with tainted index 0] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllIntentSinks():void, 8, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Intent Intent.setClassName(String,String) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllIntentSinks():void, 9, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Intent Intent.setData(Uri) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllIntentSinks():void, 10, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Intent Intent.setDataAndNormalize(Uri) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllIntentSinks():void, 11, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Intent Intent.setDataAndType(Uri,String) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllIntentSinks():void, 12, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Intent Intent.setDataAndTypeAndNormalize(Uri,String) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.callAllIntentSinks():void, 13, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Intent Intent.setPackage(String) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.subclassCallBad(codetoanalyze.java.quandary.IntentSubclass,codetoanalyze.java.quandary.ContextSubclass):void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void ContextSubclass.startActivity(Intent) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.reuseIntentBad(android.app.Activity):void, 1, INSECURE_INTENT_HANDLING, no_bucket, ERROR, [Return from Intent Activity.getIntent(),Call to void Activity.startActivity(Intent) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.extraToDataBad():void, 5, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Intent Intent.setData(Uri) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.extraToDataBad():void, 5, UNTRUSTED_INTENT_CREATION, no_bucket, ERROR, [Return from String Intent.getStringExtra(String),Call to Intent Intent.setData(Uri) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.extraToDataBad():void, 7, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Intent Intent.setData(Uri) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.extraToDataBad():void, 7, UNTRUSTED_INTENT_CREATION, no_bucket, ERROR, [Return from String Intent.getStringExtra(String),Call to Intent Intent.setData(Uri) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.startWithUri1Bad(android.net.Uri):void, 1, CREATE_INTENT_FROM_URI, no_bucket, ERROR, [Return from Intent.(String,Uri),Call to void Activity.startActivity(Intent) with tainted index 1] -codetoanalyze/java/quandary/Intents.java, codetoanalyze.java.quandary.Intents.startWithUri2Bad(android.net.Uri):void, 1, CREATE_INTENT_FROM_URI, no_bucket, ERROR, [Return from Intent.(String,Uri,Context,Class),Call to void Activity.startActivity(Intent) with tainted index 1] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.returnSourceDirectBad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data return*,Return from Object Interprocedural.returnSourceDirect(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.returnSourceDirectViaVarBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data return*,Return from Object Interprocedural.returnSourceDirect(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.returnSourceIndirectBad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data return*,Return from Object Interprocedural.returnSourceDirect() with tainted data return*,Return from Object Interprocedural.returnSourceIndirect(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.returnSourceViaFieldBad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data return.f*,Return from Interprocedural$Obj Interprocedural.returnSourceViaField(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.returnSourceViaParameter1Bad(codetoanalyze.java.quandary.Interprocedural$Obj):void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data @val$0.f*,Return from void Interprocedural.returnSourceViaParameter1(Interprocedural$Obj),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.returnSourceViaParameter2Bad(codetoanalyze.java.quandary.Interprocedural$Obj,codetoanalyze.java.quandary.Interprocedural$Obj):void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.returnSourceViaGlobalBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data quandary.Interprocedural.sGlobal*,Return from void Interprocedural.returnSourceViaGlobal(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.callSinkParam1Bad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkParam1(Object,Object) with tainted index 0,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.callSinkParam2Bad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkParam2(Object,Object) with tainted index 1,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.callSinkOnFieldDirectBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkOnFieldDirect() with tainted index 0,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.callSinkOnFieldIndirectBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkOnFieldIndirect(Interprocedural$Obj) with tainted index 0,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.callSinkOnLocalBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkOnLocal() with tainted index 0,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.callSinkOnGlobalBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkOnGlobal(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.setGlobalThenCallSinkBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkOnGlobal(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.getGlobalThenCallSinkBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.getGlobalThenCallSink(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.callSinkNoTripleReportBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkParam1(Object,Object) with tainted index 0,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.callSinkNoTripleReportBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkParam2(Object,Object) with tainted index 1,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.singlePassthroughBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.doublePassthroughBad():void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.FP_trackParamsOk():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data return*,Return from Object Interprocedural.returnSourceConditional(boolean),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.FP_reassignInCallee():void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.irrelevantPassthroughsIntraprocedural(java.lang.Object):java.lang.Object, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.irrelevantPassthroughsSourceInterprocedural(java.lang.Object):java.lang.Object, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data return,Return from Object Interprocedural.returnSourceIrrelevantPassthrough(Object),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.irrelevantPassthroughsSinkInterprocedural(java.lang.Object):java.lang.Object, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to Object Interprocedural.callSinkIrrelevantPassthrough(Object) with tainted index 0,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.irrelevantPassthroughsSourceAndSinkInterprocedural(java.lang.Object):java.lang.Object, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data return,Return from Object Interprocedural.returnSourceIrrelevantPassthrough(Object),Call to Object Interprocedural.callSinkIrrelevantPassthrough(Object) with tainted index 0,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.callSinkVariadicBad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkVariadic(Object[]) with tainted index 0,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.FP_divergenceInCallee():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.callSinkThenDivergeBad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkThenDiverge(Object) with tainted index 0,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.callDeepSinkIndirectBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkIndirectOnParam(Object) with tainted index 1,Call to void Interprocedural.callSinkOnParam(Object) with tainted index 1,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.callDeepSink1Bad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkA(Interprocedural$Obj) with tainted index 1,Call to void Interprocedural.callSink1(Interprocedural$Obj) with tainted index 1,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.callDeepSink3Bad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkC(Interprocedural$Obj) with tainted index 1,Call to void Interprocedural.callSink3(Interprocedural$Obj) with tainted index 1,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Interprocedural.java, codetoanalyze.java.quandary.Interprocedural.callDeepSink4Bad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkD(Interprocedural$Obj) with tainted index 1,Call to void Interprocedural.callSink4(Interprocedural$Obj) with tainted index 1,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 36, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from double Location.getAltitude(),Call to int Log.e(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 36, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from float Location.getBearing(),Call to int Log.e(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 36, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from double Location.getLatitude(),Call to int Log.e(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 36, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from double Location.getLongitude(),Call to int Log.e(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 36, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from float Location.getSpeed(),Call to int Log.e(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 36, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getDeviceId(),Call to int Log.e(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 36, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getLine1Number(),Call to int Log.e(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 36, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getSimSerialNumber(),Call to int Log.e(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 36, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getSubscriberId(),Call to int Log.e(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 36, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getVoiceMailNumber(),Call to int Log.e(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 37, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from double Location.getAltitude(),Call to int Log.println(int,String,String) with tainted index 2] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 37, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from float Location.getBearing(),Call to int Log.println(int,String,String) with tainted index 2] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 37, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from double Location.getLatitude(),Call to int Log.println(int,String,String) with tainted index 2] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 37, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from double Location.getLongitude(),Call to int Log.println(int,String,String) with tainted index 2] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 37, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from float Location.getSpeed(),Call to int Log.println(int,String,String) with tainted index 2] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 37, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getDeviceId(),Call to int Log.println(int,String,String) with tainted index 2] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 37, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getLine1Number(),Call to int Log.println(int,String,String) with tainted index 2] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 37, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getSimSerialNumber(),Call to int Log.println(int,String,String) with tainted index 2] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 37, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getSubscriberId(),Call to int Log.println(int,String,String) with tainted index 2] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 37, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getVoiceMailNumber(),Call to int Log.println(int,String,String) with tainted index 2] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 38, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from double Location.getAltitude(),Call to int Log.w(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 38, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from float Location.getBearing(),Call to int Log.w(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 38, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from double Location.getLatitude(),Call to int Log.w(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 38, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from double Location.getLongitude(),Call to int Log.w(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 38, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from float Location.getSpeed(),Call to int Log.w(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 38, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getDeviceId(),Call to int Log.w(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 38, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getLine1Number(),Call to int Log.w(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 38, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getSimSerialNumber(),Call to int Log.w(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 38, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getSubscriberId(),Call to int Log.w(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 38, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getVoiceMailNumber(),Call to int Log.w(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 39, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from double Location.getAltitude(),Call to int Log.wtf(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 39, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from float Location.getBearing(),Call to int Log.wtf(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 39, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from double Location.getLatitude(),Call to int Log.wtf(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 39, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from double Location.getLongitude(),Call to int Log.wtf(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 39, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from float Location.getSpeed(),Call to int Log.wtf(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 39, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getDeviceId(),Call to int Log.wtf(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 39, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getLine1Number(),Call to int Log.wtf(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 39, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getSimSerialNumber(),Call to int Log.wtf(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 39, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getSubscriberId(),Call to int Log.wtf(String,String) with tainted index 1] -codetoanalyze/java/quandary/LoggingPrivateData.java, codetoanalyze.java.quandary.LoggingPrivateData.logAllSourcesBad(android.location.Location,android.telephony.TelephonyManager):void, 39, LOGGING_PRIVATE_DATA, no_bucket, ERROR, [Return from String TelephonyManager.getVoiceMailNumber(),Call to int Log.wtf(String,String) with tainted index 1] -codetoanalyze/java/quandary/Recursion.java, codetoanalyze.java.quandary.Recursion.callSinkThenDivergeBad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Recursion.callSinkThenDiverge(Object) with tainted index 0,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Recursion.java, codetoanalyze.java.quandary.Recursion.safeRecursionCallSinkBad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Recursion.safeRecursionCallSink(int,Object) with tainted index 1,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Serialization.java, codetoanalyze.java.quandary.Serialization.taintedObjectInputStreamBad():java.lang.Object, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to ObjectInputStream.(InputStream) with tainted index 1] -codetoanalyze/java/quandary/Services.java, codetoanalyze.java.quandary.Service1.serviceMethodBad(java.lang.String):void, 1, SHELL_INJECTION_RISK, no_bucket, ERROR, [Return from void Service1.serviceMethodBad(String),Call to Process Runtime.exec(String) with tainted index 1] -codetoanalyze/java/quandary/Services.java, codetoanalyze.java.quandary.Service1.paramToSql1Bad(java.lang.String):void, 1, SQL_INJECTION_RISK, no_bucket, ERROR, [Return from void Service1.paramToSql1Bad(String),Call to boolean Statement.execute(String) with tainted index 1] -codetoanalyze/java/quandary/Services.java, codetoanalyze.java.quandary.Service1.paramToSql2Bad(java.lang.String):void, 1, USER_CONTROLLED_SQL_RISK, no_bucket, ERROR, [Return from void Service1.paramToSql2Bad(String),Call to long Statement.executeLargeUpdate(String) with tainted index 1] -codetoanalyze/java/quandary/Services.java, codetoanalyze.java.quandary.Service1.paramToSql3Bad(java.lang.String):void, 1, USER_CONTROLLED_SQL_RISK, no_bucket, ERROR, [Return from void Service1.paramToSql3Bad(String),Call to ResultSet Statement.executeQuery(String) with tainted index 1] -codetoanalyze/java/quandary/Services.java, codetoanalyze.java.quandary.Service1.paramToSql4Bad(java.lang.String):void, 1, USER_CONTROLLED_SQL_RISK, no_bucket, ERROR, [Return from void Service1.paramToSql4Bad(String),Call to int Statement.executeUpdate(String) with tainted index 1] -codetoanalyze/java/quandary/Services.java, codetoanalyze.java.quandary.Service1.paramToSql5Bad(java.lang.String):void, 1, SQL_INJECTION_RISK, no_bucket, ERROR, [Return from void Service1.paramToSql5Bad(String),Call to void Statement.addBatch(String) with tainted index 1] -codetoanalyze/java/quandary/Services.java, codetoanalyze.java.quandary.Service1.packageProtectedServiceMethodBad(java.lang.String):void, 1, SHELL_INJECTION_RISK, no_bucket, ERROR, [Return from void Service1.packageProtectedServiceMethodBad(String),Call to Process Runtime.exec(String) with tainted index 1] -codetoanalyze/java/quandary/Strings.java, Strings.viaStringBuilderSugarBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Strings.java, Strings.viaStringBuilderBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Strings.java, Strings.viaStringBuilderIgnoreReturnBad():void, 5, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Strings.java, Strings.viaStringBufferBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Strings.java, Strings.viaStringBufferIgnoreReturnBad():void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Strings.java, Strings.viaFormatterBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Strings.java, Strings.viaFormatterIgnoreReturnBad():void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Strings.java, Strings.viaStringFormatVarArgsDirectBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/Strings.java, Strings.viaStringFormatVarArgsIndirectBad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Strings.viaStringFormatVarArgsIndirect(Object) with tainted index 1,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/TaintExample.java, codetoanalyze.java.quandary.TaintExample.simpleTaintErrorWithModelMethods():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/TaintExample.java, codetoanalyze.java.quandary.TaintExample.interprocTaintErrorWithModelMethods1():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data return*,Return from Object TaintExample.returnTaintedSourceModelMethods(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/TaintExample.java, codetoanalyze.java.quandary.TaintExample.interprocTaintErrorWithModelMethods2():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void TaintExample.callSinkMethodModelMethods(Object) with tainted index 1,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/TaintExample.java, codetoanalyze.java.quandary.TaintExample.interprocTaintErrorWithModelMethods3():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data return*,Return from Object TaintExample.returnTaintedSourceModelMethods(),Call to void TaintExample.callSinkMethodModelMethods(Object) with tainted index 1,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/TaintedFormals.java, codetoanalyze.java.quandary.TaintedFormals.taintedContextBad(java.lang.String,android.content.Intent,java.lang.Integer):void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from void TaintedFormals.taintedContextBad(String,Intent,Integer),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/TaintedFormals.java, codetoanalyze.java.quandary.TaintedFormals.taintedContextBad(java.lang.String,android.content.Intent,java.lang.Integer):void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from void TaintedFormals.taintedContextBad(String,Intent,Integer),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/TaintedFormals.java, codetoanalyze.java.quandary.TaintedFormals.taintedContextBad(java.lang.String,android.content.Intent,java.lang.Integer):void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from void TaintedFormals.taintedContextBad(String,Intent,Integer),Call to void TaintedFormals.callSink(Object) with tainted index 1,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/TaintedFormals.java, codetoanalyze.java.quandary.TaintedFormals.taintedContextBad(java.lang.String,android.content.Intent,java.lang.Integer):void, 5, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from void TaintedFormals.taintedContextBad(String,Intent,Integer),Call to void TaintedFormals.callSink(Object) with tainted index 1,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/TaintedFormals.java, codetoanalyze.java.quandary.TaintedFormals.callTaintedContextBad1(java.lang.String):void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object TaintedFormals.taintedContextBad(String) with tainted data return*,Return from Object TaintedFormals.taintedContextBad(String),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/TaintedFormals.java, codetoanalyze.java.quandary.TaintedFormals.callTaintedContextBad2():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void TaintedFormals.taintedContextBad(String,Intent,Integer) with tainted index 2,Call to ComponentName ContextWrapper.startService(Intent) with tainted index 1] -codetoanalyze/java/quandary/Traces.java, codetoanalyze.java.quandary.Traces.sourceMethod():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Traces.callSameSink(Obj,Obj,Obj,Obj) with tainted index 2,Call to void Traces.callMySinkIndirect(Obj) with tainted index 1,Call to void Traces.callMySink(Obj) with tainted index 1,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/UnknownCode.java, codetoanalyze.java.quandary.UnknownCode.propagateViaUnknownConstructorBad():void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/UnknownCode.java, codetoanalyze.java.quandary.UnknownCode.callUnknownSetterBad(android.content.Intent):void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/UnknownCode.java, codetoanalyze.java.quandary.UnknownCode.propagateEmptyBad():void, 6, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/UnknownCode.java, codetoanalyze.java.quandary.UnknownCode.propagateEmptyBad():void, 7, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/UnknownCode.java, codetoanalyze.java.quandary.UnknownCode.callPropagateFootprintBad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void UnknownCode.propagateFootprint(String) with tainted index 1,Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/UnknownCode.java, codetoanalyze.java.quandary.UnknownCode.propagateViaInterfaceCodeBad(codetoanalyze.java.quandary.UnknownCode$Interface):void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/UnknownCode.java, codetoanalyze.java.quandary.UnknownCode.propagateViaUnknownNativeCodeBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/UnknownCode.java, codetoanalyze.java.quandary.UnknownCode.propagateViaUnknownAbstractCodeBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/UserControlledStrings.java, codetoanalyze.java.quandary.UserControlledStrings.readClipboardSourcesBad():void, 1, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from CharSequence ClipboardManager.getText(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/UserControlledStrings.java, codetoanalyze.java.quandary.UserControlledStrings.readClipboardSourcesBad():void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from ClipData ClipboardManager.getPrimaryClip(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/UserControlledStrings.java, codetoanalyze.java.quandary.UserControlledStrings.readClipboardSourcesBad():void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from ClipData ClipboardManager.getPrimaryClip(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/UserControlledStrings.java, codetoanalyze.java.quandary.UserControlledStrings.readClipboardSourcesBad():void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from ClipData ClipboardManager.getPrimaryClip(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/UserControlledStrings.java, codetoanalyze.java.quandary.UserControlledStrings.readClipboardSourcesBad():void, 5, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from ClipData ClipboardManager.getPrimaryClip(),Call to void InferTaint.inferSensitiveSink(Object) with tainted index 0] -codetoanalyze/java/quandary/UserControlledStrings.java, codetoanalyze.java.quandary.UserControlledStrings.clipboardToHtmlBad():android.text.Spanned, 1, CROSS_SITE_SCRIPTING, no_bucket, ERROR, [Return from CharSequence ClipboardManager.getText(),Call to Spanned Html.fromHtml(String) with tainted index 0] -codetoanalyze/java/quandary/UserControlledStrings.java, codetoanalyze.java.quandary.UserControlledStrings.editTextToHtmlBad():android.text.Spanned, 1, CROSS_SITE_SCRIPTING, no_bucket, ERROR, [Return from Editable EditText.getText(),Call to Spanned Html.fromHtml(String) with tainted index 0] -codetoanalyze/java/quandary/UserControlledStrings.java, codetoanalyze.java.quandary.UserControlledStrings.clipboardToShellDirectBad():void, 1, SHELL_INJECTION, no_bucket, ERROR, [Return from CharSequence ClipboardManager.getText(),Call to Process Runtime.exec(String) with tainted index 1] -codetoanalyze/java/quandary/UserControlledStrings.java, codetoanalyze.java.quandary.UserControlledStrings.clipboardToShellArrayBad():void, 2, SHELL_INJECTION, no_bucket, ERROR, [Return from CharSequence ClipboardManager.getText(),Call to Process Runtime.exec(String[]) with tainted index 1] -codetoanalyze/java/quandary/UserControlledStrings.java, codetoanalyze.java.quandary.UserControlledStrings.clipboardToProcessBuilder1Bad():java.lang.ProcessBuilder, 1, SHELL_INJECTION, no_bucket, ERROR, [Return from CharSequence ClipboardManager.getText(),Call to ProcessBuilder.(String[]) with tainted index 1] -codetoanalyze/java/quandary/UserControlledStrings.java, codetoanalyze.java.quandary.UserControlledStrings.clipboardToProcessBuilder2Bad():java.lang.ProcessBuilder, 1, SHELL_INJECTION, no_bucket, ERROR, [Return from CharSequence ClipboardManager.getText(),Call to ProcessBuilder.(String[]) with tainted index 1] -codetoanalyze/java/quandary/UserControlledStrings.java, codetoanalyze.java.quandary.UserControlledStrings.clipboardToProcessBuilder3Bad(java.lang.ProcessBuilder):java.lang.ProcessBuilder, 1, SHELL_INJECTION, no_bucket, ERROR, [Return from CharSequence ClipboardManager.getText(),Call to ProcessBuilder ProcessBuilder.command(String[]) with tainted index 1] -codetoanalyze/java/quandary/UserControlledStrings.java, codetoanalyze.java.quandary.UserControlledStrings.clipboardToProcessBuilder4Bad(java.lang.ProcessBuilder):java.lang.ProcessBuilder, 3, SHELL_INJECTION, no_bucket, ERROR, [Return from CharSequence ClipboardManager.getText(),Call to ProcessBuilder ProcessBuilder.command(List) with tainted index 1] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews.callWebviewSinks(android.webkit.WebView):void, 3, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void WebView.evaluateJavascript(String,ValueCallback) with tainted index 1] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews.callWebviewSinks(android.webkit.WebView):void, 4, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void WebView.loadData(String,String,String) with tainted index 1] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews.callWebviewSinks(android.webkit.WebView):void, 5, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void WebView.loadDataWithBaseURL(String,String,String,String,String) with tainted index 2] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews.callWebviewSinks(android.webkit.WebView):void, 6, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void WebView.loadUrl(String) with tainted index 1] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews.callWebviewSinks(android.webkit.WebView):void, 7, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void WebView.postUrl(String,byte[]) with tainted index 1] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews.callWebviewSinks(android.webkit.WebView):void, 8, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void WebView.postWebMessage(WebMessage,Uri) with tainted index 2] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews$MyWebViewClient.onLoadResource(android.webkit.WebView,java.lang.String):void, 2, UNTRUSTED_INTENT_CREATION, no_bucket, ERROR, [Return from void WebViews$MyWebViewClient.onLoadResource(WebView,String),Call to Intent Intent.parseUri(String,int) with tainted index 0] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews$MyWebViewClient.onLoadResource(android.webkit.WebView,java.lang.String):void, 3, CREATE_INTENT_FROM_URI, no_bucket, ERROR, [Return from Intent Intent.parseUri(String,int),Call to void Activity.startActivity(Intent) with tainted index 1] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews$MyWebViewClient.shouldInterceptRequest(android.webkit.WebView,android.webkit.WebResourceRequest):android.webkit.WebResourceResponse, 1, CREATE_INTENT_FROM_URI, no_bucket, ERROR, [Return from Intent.(String,Uri),Call to void Activity.startActivity(Intent) with tainted index 1] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews$MyWebViewClient.webResourceToFileBad(android.webkit.WebResourceRequest):java.io.File, 1, UNTRUSTED_FILE, no_bucket, ERROR, [Return from Uri WebResourceRequest.getUrl(),Call to File.(String) with tainted index 1] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews$MyWebViewClient.shouldOverrideUrlLoading(android.webkit.WebView,java.lang.String):boolean, 2, UNTRUSTED_INTENT_CREATION, no_bucket, ERROR, [Return from boolean WebViews$MyWebViewClient.shouldOverrideUrlLoading(WebView,String),Call to Intent Intent.parseUri(String,int) with tainted index 0] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews$MyWebViewClient.shouldOverrideUrlLoading(android.webkit.WebView,java.lang.String):boolean, 3, CREATE_INTENT_FROM_URI, no_bucket, ERROR, [Return from Intent Intent.parseUri(String,int),Call to void Activity.startActivity(Intent) with tainted index 1] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews$MyWebChromeClient.onJsAlert(android.webkit.WebView,java.lang.String,java.lang.String,android.webkit.JsResult):boolean, 2, UNTRUSTED_INTENT_CREATION, no_bucket, ERROR, [Return from boolean WebViews$MyWebChromeClient.onJsAlert(WebView,String,String,JsResult),Call to Intent Intent.parseUri(String,int) with tainted index 0] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews$MyWebChromeClient.onJsAlert(android.webkit.WebView,java.lang.String,java.lang.String,android.webkit.JsResult):boolean, 3, CREATE_INTENT_FROM_URI, no_bucket, ERROR, [Return from Intent Intent.parseUri(String,int),Call to void Activity.startActivity(Intent) with tainted index 1] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews$MyWebChromeClient.onJsBeforeUnload(android.webkit.WebView,java.lang.String,java.lang.String,android.webkit.JsResult):boolean, 2, UNTRUSTED_INTENT_CREATION, no_bucket, ERROR, [Return from boolean WebViews$MyWebChromeClient.onJsBeforeUnload(WebView,String,String,JsResult),Call to Intent Intent.parseUri(String,int) with tainted index 0] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews$MyWebChromeClient.onJsBeforeUnload(android.webkit.WebView,java.lang.String,java.lang.String,android.webkit.JsResult):boolean, 3, CREATE_INTENT_FROM_URI, no_bucket, ERROR, [Return from Intent Intent.parseUri(String,int),Call to void Activity.startActivity(Intent) with tainted index 1] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews$MyWebChromeClient.onJsConfirm(android.webkit.WebView,java.lang.String,java.lang.String,android.webkit.JsResult):boolean, 2, UNTRUSTED_INTENT_CREATION, no_bucket, ERROR, [Return from boolean WebViews$MyWebChromeClient.onJsConfirm(WebView,String,String,JsResult),Call to Intent Intent.parseUri(String,int) with tainted index 0] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews$MyWebChromeClient.onJsConfirm(android.webkit.WebView,java.lang.String,java.lang.String,android.webkit.JsResult):boolean, 3, CREATE_INTENT_FROM_URI, no_bucket, ERROR, [Return from Intent Intent.parseUri(String,int),Call to void Activity.startActivity(Intent) with tainted index 1] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews$MyWebChromeClient.onJsPrompt(android.webkit.WebView,java.lang.String,java.lang.String,java.lang.String,android.webkit.JsPromptResult):boolean, 2, UNTRUSTED_INTENT_CREATION, no_bucket, ERROR, [Return from boolean WebViews$MyWebChromeClient.onJsPrompt(WebView,String,String,String,JsPromptResult),Call to Intent Intent.parseUri(String,int) with tainted index 0] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews$MyWebChromeClient.onJsPrompt(android.webkit.WebView,java.lang.String,java.lang.String,java.lang.String,android.webkit.JsPromptResult):boolean, 3, CREATE_INTENT_FROM_URI, no_bucket, ERROR, [Return from Intent Intent.parseUri(String,int),Call to void Activity.startActivity(Intent) with tainted index 1] -codetoanalyze/java/quandary/WebViews.java, codetoanalyze.java.quandary.WebViews.callWebviewSubclassSink(codetoanalyze.java.quandary.WebViews$MyWebView):void, 2, QUANDARY_TAINT_ERROR, no_bucket, ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void WebView.evaluateJavascript(String,ValueCallback) with tainted index 1] diff --git a/infer/tests/codetoanalyze/objc/quandary/Makefile b/infer/tests/codetoanalyze/objc/quandary/Makefile deleted file mode 100644 index ffd32fdcbb5..00000000000 --- a/infer/tests/codetoanalyze/objc/quandary/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (c) Facebook, Inc. and its affiliates. -# -# This source code is licensed under the MIT license found in the -# LICENSE file in the root directory of this source tree. - -TESTS_DIR = ../../.. - -CLANG_OPTIONS = -c $(OBJC_CLANG_OPTIONS) - -INFER_OPTIONS = --quandary-only --no-filtering --debug-exceptions --project-root $(TESTS_DIR) -INFERPRINT_OPTIONS = --issues-tests - -SOURCES = \ - $(wildcard *.m) \ - -include $(TESTS_DIR)/clang.make -include $(TESTS_DIR)/objc.make diff --git a/infer/tests/codetoanalyze/objc/quandary/basics.m b/infer/tests/codetoanalyze/objc/quandary/basics.m deleted file mode 100644 index add8c44c7c9..00000000000 --- a/infer/tests/codetoanalyze/objc/quandary/basics.m +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#import - -@interface InferTaint : NSObject { -} - -+ (NSObject*)source; -+ (void)sink:(NSObject*)param; -+ (void)notASink:(NSObject*)param; -@end - -void FN_callSinkDirectBad() { - NSObject* source = [InferTaint source]; - [InferTaint sink:source]; -} - -void callSinkOnNonSourceOk() { - NSObject* source = [NSObject new]; - [InferTaint sink:source]; -} - -void callNonSinkOnSourceOk() { - NSObject* source = [InferTaint source]; - [InferTaint notASink:source]; -} diff --git a/infer/tests/codetoanalyze/objc/quandary/issues.exp b/infer/tests/codetoanalyze/objc/quandary/issues.exp deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/scripts/toplevel_init b/scripts/toplevel_init index ba6f7f38815..2634bafd25c 100644 --- a/scripts/toplevel_init +++ b/scripts/toplevel_init @@ -28,7 +28,6 @@ open BO;; open Pulselib;; open Checkers;; open Costlib;; -open Quandary;; open Topllib;; open Concurrency;; open Labs;; diff --git a/website/docs/all-checkers.md b/website/docs/all-checkers.md index c9222f982e0..ea58e3e3d23 100644 --- a/website/docs/all-checkers.md +++ b/website/docs/all-checkers.md @@ -113,14 +113,6 @@ Detects pure (side-effect-free) functions. A different implementation of "impuri [Visit here for more information.](/docs/next/checker-purity) -## Quandary - -The Quandary taint analysis detects flows of values between sources and sinks, except if the value went through a "sanitizer". In addition to some defaults, users can specify their own sources, sinks, and sanitizers functions. - -**\*\*\*DEPRECATED\*\*\*** Taint analysis is now supported by the Pulse checker and Quandary will be removed in the next release. - -[Visit here for more information.](/docs/next/checker-quandary) - ## RacerD Thread safety analysis. @@ -168,4 +160,3 @@ Detect various kinds of situations when no progress is being made because of con Detect errors based on user-provided state machines describing temporal properties over multiple objects. [Visit here for more information.](/docs/next/checker-topl) - diff --git a/website/docs/checker-quandary.md b/website/docs/checker-quandary.md deleted file mode 100644 index 8f514b81cd3..00000000000 --- a/website/docs/checker-quandary.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: "Quandary" -description: "The Quandary taint analysis detects flows of values between sources and sinks, except if the value went through a \"sanitizer\". In addition to some defaults, users can specify their own sources, sinks, and sanitizers functions." ---- - -The Quandary taint analysis detects flows of values between sources and sinks, except if the value went through a "sanitizer". In addition to some defaults, users can specify their own sources, sinks, and sanitizers functions. - -**\*\*\*DEPRECATED\*\*\*** Taint analysis is now supported by the Pulse checker and Quandary will be removed in the next release. - -Activate with `--quandary`. - -Supported languages: -- C/C++/ObjC: Yes -- C#/.Net: No -- Erlang: No -- Hack: No -- Java: Yes -- Python: No - -Quandary is a static taint analyzer that identifies a variety of unsafe -information flows. It has a small list of built-in -[sources](https://github.com/facebook/infer/blob/main/infer/src/quandary/JavaTrace.ml#L36) -and -[sinks](https://github.com/facebook/infer/blob/main/infer/src/quandary/JavaTrace.ml#L178), -and you can define custom sources and sinks in your `.inferconfig` file (see -example -[here](https://github.com/facebook/infer/blob/main/infer/tests/codetoanalyze/java/quandary/.inferconfig)). - - -## List of Issue Types - -The following issue types are reported by this checker: -- [CREATE_INTENT_FROM_URI](/docs/next/all-issue-types#create_intent_from_uri) -- [CROSS_SITE_SCRIPTING](/docs/next/all-issue-types#cross_site_scripting) -- [EXPOSED_INSECURE_INTENT_HANDLING](/docs/next/all-issue-types#exposed_insecure_intent_handling) -- [INSECURE_INTENT_HANDLING](/docs/next/all-issue-types#insecure_intent_handling) -- [JAVASCRIPT_INJECTION](/docs/next/all-issue-types#javascript_injection) -- [LOGGING_PRIVATE_DATA](/docs/next/all-issue-types#logging_private_data) -- [QUANDARY_TAINT_ERROR](/docs/next/all-issue-types#quandary_taint_error) -- [SHELL_INJECTION](/docs/next/all-issue-types#shell_injection) -- [SHELL_INJECTION_RISK](/docs/next/all-issue-types#shell_injection_risk) -- [SQL_INJECTION](/docs/next/all-issue-types#sql_injection) -- [SQL_INJECTION_RISK](/docs/next/all-issue-types#sql_injection_risk) -- [UNTRUSTED_BUFFER_ACCESS](/docs/next/all-issue-types#untrusted_buffer_access) -- [UNTRUSTED_DESERIALIZATION](/docs/next/all-issue-types#untrusted_deserialization) -- [UNTRUSTED_DESERIALIZATION_RISK](/docs/next/all-issue-types#untrusted_deserialization_risk) -- [UNTRUSTED_ENVIRONMENT_CHANGE_RISK](/docs/next/all-issue-types#untrusted_environment_change_risk) -- [UNTRUSTED_FILE](/docs/next/all-issue-types#untrusted_file) -- [UNTRUSTED_FILE_RISK](/docs/next/all-issue-types#untrusted_file_risk) -- [UNTRUSTED_HEAP_ALLOCATION](/docs/next/all-issue-types#untrusted_heap_allocation) -- [UNTRUSTED_INTENT_CREATION](/docs/next/all-issue-types#untrusted_intent_creation) -- [UNTRUSTED_URL_RISK](/docs/next/all-issue-types#untrusted_url_risk) -- [UNTRUSTED_VARIABLE_LENGTH_ARRAY](/docs/next/all-issue-types#untrusted_variable_length_array) -- [USER_CONTROLLED_SQL_RISK](/docs/next/all-issue-types#user_controlled_sql_risk)