diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 0a8267a76..66dc95a19 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -2297,6 +2297,16 @@ let inferconfig_file = find (Sys.getcwd ()) |> Option.map ~f:(fun dir -> dir ^/ CommandDoc.inferconfig_file) +let quandaryBO_filtered_issues = + ref + IssueType. + [ buffer_overrun_u5 + ; buffer_overrun_l5 + ; buffer_overrun_l4 + ; untrusted_buffer_access + ; untrusted_heap_allocation ] + + let post_parsing_initialization command_opt = if CommandLineOption.is_originator then ( (* let subprocesses know where the toplevel process' results dir is *) @@ -2435,6 +2445,11 @@ let post_parsing_initialization command_opt = linters := true | Some (CaptureOnly | Checkers | CompileOnly) | None -> () ) ; + if !quandaryBO then + quandaryBO_filtered_issues := + List.filter !quandaryBO_filtered_issues ~f:(fun issue -> + let enabled = issue.IssueType.enabled in + IssueType.set_enabled issue true ; not enabled ) ; Option.value ~default:InferCommand.Run command_opt @@ -2858,6 +2873,8 @@ and quandary = !quandary and quandaryBO = !quandaryBO +and quandaryBO_filtered_issues = !quandaryBO_filtered_issues + and quandary_endpoints = !quandary_endpoints and quandary_sanitizers = !quandary_sanitizers diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index 704512d6d..c6e8fe945 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -695,3 +695,6 @@ val print_usage_exit : unit -> 'a val java_package_is_external : string -> bool (** Check if a Java package is external to the repository *) + +val quandaryBO_filtered_issues : IssueType.t list +(* List of issues that are enabled by QuandaryBO but should not be in the final report.json *) diff --git a/infer/src/base/IssueType.ml b/infer/src/base/IssueType.ml index 08c12481a..6ce4cc31c 100644 --- a/infer/src/base/IssueType.ml +++ b/infer/src/base/IssueType.ml @@ -108,13 +108,13 @@ let buffer_overrun_l2 = from_string "BUFFER_OVERRUN_L2" let buffer_overrun_l3 = from_string "BUFFER_OVERRUN_L3" -let buffer_overrun_l4 = from_string "BUFFER_OVERRUN_L4" +let buffer_overrun_l4 = from_string ~enabled:false "BUFFER_OVERRUN_L4" -let buffer_overrun_l5 = from_string "BUFFER_OVERRUN_L5" +let buffer_overrun_l5 = from_string ~enabled:false "BUFFER_OVERRUN_L5" let buffer_overrun_s2 = from_string "BUFFER_OVERRUN_S2" -let buffer_overrun_u5 = from_string "BUFFER_OVERRUN_U5" +let buffer_overrun_u5 = from_string ~enabled:false "BUFFER_OVERRUN_U5" let cannot_star = from_string "Cannot_star" @@ -381,7 +381,7 @@ let use_after_lifetime = from_string "USE_AFTER_LIFETIME" let user_controlled_sql_risk = from_string "USER_CONTROLLED_SQL_RISK" -let untrusted_buffer_access = from_string "UNTRUSTED_BUFFER_ACCESS" +let untrusted_buffer_access = from_string ~enabled:false "UNTRUSTED_BUFFER_ACCESS" let untrusted_deserialization = from_string "UNTRUSTED_DESERIALIZATION" @@ -389,7 +389,7 @@ let untrusted_file = from_string "UNTRUSTED_FILE" let untrusted_file_risk = from_string "UNTRUSTED_FILE_RISK" -let untrusted_heap_allocation = from_string "UNTRUSTED_HEAP_ALLOCATION" +let untrusted_heap_allocation = from_string ~enabled:false "UNTRUSTED_HEAP_ALLOCATION" let untrusted_intent_creation = from_string "UNTRUSTED_INTENT_CREATION" diff --git a/infer/src/quandary/quandaryBO.ml b/infer/src/quandary/quandaryBO.ml index 923df8c0a..3f28a5081 100644 --- a/infer/src/quandary/quandaryBO.ml +++ b/infer/src/quandary/quandaryBO.ml @@ -103,14 +103,14 @@ let update_issues all_issues = let inferbo_issues = inferbo_alloc_issues @ inferbo_access_issues @ [IssueType.unreachable_code_after] in + let filtered_issues = Config.quandaryBO_filtered_issues in let all_issues_filtered = List.filter ~f:(fun issue -> - ( Config.quandary - || not (List.mem quandary_issues issue.Issue.err_key.err_name ~equal:IssueType.equal) ) - && ( Config.bufferoverrun - || not (List.mem inferbo_issues issue.Issue.err_key.err_name ~equal:IssueType.equal) ) - ) + let issue_in ls = List.mem ls issue.Issue.err_key.err_name ~equal:IssueType.equal in + (Config.quandary || not (issue_in quandary_issues)) + && (Config.bufferoverrun || not (issue_in inferbo_issues)) + && not (issue_in filtered_issues) ) all_issues in List.rev_append all_issues_filtered quandaryBO_issues diff --git a/infer/tests/codetoanalyze/cpp/quandaryBO/Makefile b/infer/tests/codetoanalyze/cpp/quandaryBO/Makefile index a0ba203ee..83bd6aa29 100644 --- a/infer/tests/codetoanalyze/cpp/quandaryBO/Makefile +++ b/infer/tests/codetoanalyze/cpp/quandaryBO/Makefile @@ -1,19 +1,44 @@ -# Copyright (c) 2016-present, Facebook, Inc. +# Copyright (c) 2018-present, Facebook, Inc. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. - TESTS_DIR = ../../.. -ANALYZER = checkers -# see explanations in cpp/errors/Makefile for the custom isystem -CLANG_OPTIONS = -x c++ -std=c++11 -nostdinc++ -isystem$(ROOT_DIR) -isystem$(CLANG_INCLUDES)/c++/v1/ -c -INFER_OPTIONS = \ - -F --quandaryBO-only --passthroughs --debug-exceptions \ +OPTIONS_1 = \ + --quandaryBO-only --passthroughs --debug-exceptions \ --project-root $(TESTS_DIR) \ -INFERPRINT_OPTIONS = --issues-tests +OPTIONS_2 = \ + --quandaryBO-only --quandary --enable-issue-type UNTRUSTED_BUFFER_ACCESS --passthroughs --debug-exceptions \ + --project-root $(TESTS_DIR) \ + +OPTIONS_3 = \ + --quandaryBO-only --bufferoverrun --enable-issue-type BUFFER_OVERRUN_U5 --passthroughs --debug-exceptions \ + --project-root $(TESTS_DIR) \ + +test: test1 test2 test3 + +test1: + $(MAKE) -f multitest.make test TEST_SUFFIX=-t1 TEST_RESULT_SUFFIX=-t1 INFER_OPTIONS="$(OPTIONS_1)" + +test2: + $(MAKE) -f multitest.make test TEST_SUFFIX=-t2 TEST_RESULT_SUFFIX=-t2 INFER_OPTIONS="$(OPTIONS_2)" + +test3: + $(MAKE) -f multitest.make test TEST_SUFFIX=-t3 TEST_RESULT_SUFFIX=-t3 INFER_OPTIONS="$(OPTIONS_3)" + +replace: replace1 replace2 replace3 + +replace1: + $(MAKE) -f multitest.make replace TEST_SUFFIX=-t1 TEST_RESULT_SUFFIX=-t1 + +replace2: + $(MAKE) -f multitest.make replace TEST_SUFFIX=-t2 TEST_RESULT_SUFFIX=-t2 -SOURCES = $(wildcard *.cpp) +replace3: + $(MAKE) -f multitest.make replace TEST_SUFFIX=-t3 TEST_RESULT_SUFFIX=-t3 -include $(TESTS_DIR)/clang.make +clean: + $(MAKE) -f multitest.make clean TEST_SUFFIX=-t1 + $(MAKE) -f multitest.make clean TEST_SUFFIX=-t2 + $(MAKE) -f multitest.make clean TEST_SUFFIX=-t3 diff --git a/infer/tests/codetoanalyze/cpp/quandaryBO/issues.exp b/infer/tests/codetoanalyze/cpp/quandaryBO/issues.exp-t1 similarity index 100% rename from infer/tests/codetoanalyze/cpp/quandaryBO/issues.exp rename to infer/tests/codetoanalyze/cpp/quandaryBO/issues.exp-t1 diff --git a/infer/tests/codetoanalyze/cpp/quandaryBO/issues.exp-t2 b/infer/tests/codetoanalyze/cpp/quandaryBO/issues.exp-t2 new file mode 100644 index 000000000..077739e62 --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/quandaryBO/issues.exp-t2 @@ -0,0 +1,8 @@ +codetoanalyze/cpp/quandaryBO/tainted_index.cpp, basic_bad, 3, TAINTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to __array_access with tainted index 0,-----------,ArrayDeclaration,Unknown value from: __infer_taint_source,Assignment,ArrayAccess: Offset: [-oo, +oo] Size: 10] +codetoanalyze/cpp/quandaryBO/tainted_index.cpp, basic_bad, 3, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to __array_access with tainted index 0] +codetoanalyze/cpp/quandaryBO/tainted_index.cpp, memory_alloc_bad1_FN, 0, UNTRUSTED_VARIABLE_LENGTH_ARRAY, no_bucket, ERROR, [Return from __infer_taint_source,Call to __set_array_length with tainted index 1] +codetoanalyze/cpp/quandaryBO/tainted_index.cpp, memory_alloc_bad2, 3, TAINTED_MEMORY_ALLOCATION, no_bucket, ERROR, [Return from __infer_taint_source,Call to __set_array_length with tainted index 1,-----------,Unknown value from: __infer_taint_source,Assignment,Alloc: Length: [-oo, 2147483647]] +codetoanalyze/cpp/quandaryBO/tainted_index.cpp, memory_alloc_bad2, 3, UNTRUSTED_VARIABLE_LENGTH_ARRAY, no_bucket, ERROR, [Return from __infer_taint_source,Call to __set_array_length with tainted index 1] +codetoanalyze/cpp/quandaryBO/tainted_index.cpp, multi_level_bad, 2, TAINTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source with tainted data return*,Return from multi_level_source_bad,Call to multi_level_sink_bad with tainted index 0,Call to __array_access with tainted index 0,-----------,Call,Unknown value from: __infer_taint_source,Assignment,Return,Assignment,Call,ArrayDeclaration,Parameter: i,ArrayAccess: Offset: [1, +oo] Size: 10 by call to `multi_level_sink_bad` ] +codetoanalyze/cpp/quandaryBO/tainted_index.cpp, multi_level_bad, 2, UNTRUSTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source with tainted data return*,Return from multi_level_source_bad,Call to multi_level_sink_bad with tainted index 0,Call to __array_access with tainted index 0] +codetoanalyze/cpp/quandaryBO/tainted_index.cpp, overlapping_issues_good, 1, UNTRUSTED_VARIABLE_LENGTH_ARRAY, no_bucket, ERROR, [Return from __infer_taint_source with tainted data @val$0.size*,Return from overlapping_issues_source_good,Call to overlapping_issues_sink_good with tainted index 0,Call to __set_array_length with tainted index 1] diff --git a/infer/tests/codetoanalyze/cpp/quandaryBO/issues.exp-t3 b/infer/tests/codetoanalyze/cpp/quandaryBO/issues.exp-t3 new file mode 100644 index 000000000..6259d67ef --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/quandaryBO/issues.exp-t3 @@ -0,0 +1,6 @@ +codetoanalyze/cpp/quandaryBO/tainted_index.cpp, basic_bad, 3, BUFFER_OVERRUN_U5, no_bucket, ERROR, [ArrayDeclaration,Unknown value from: __infer_taint_source,Assignment,ArrayAccess: Offset: [-oo, +oo] Size: 10] +codetoanalyze/cpp/quandaryBO/tainted_index.cpp, basic_bad, 3, TAINTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source,Call to __array_access with tainted index 0,-----------,ArrayDeclaration,Unknown value from: __infer_taint_source,Assignment,ArrayAccess: Offset: [-oo, +oo] Size: 10] +codetoanalyze/cpp/quandaryBO/tainted_index.cpp, memory_alloc_bad2, 3, INFERBO_ALLOC_MAY_BE_BIG, no_bucket, ERROR, [Unknown value from: __infer_taint_source,Assignment,Alloc: Length: [-oo, 2147483647]] +codetoanalyze/cpp/quandaryBO/tainted_index.cpp, memory_alloc_bad2, 3, TAINTED_MEMORY_ALLOCATION, no_bucket, ERROR, [Return from __infer_taint_source,Call to __set_array_length with tainted index 1,-----------,Unknown value from: __infer_taint_source,Assignment,Alloc: Length: [-oo, 2147483647]] +codetoanalyze/cpp/quandaryBO/tainted_index.cpp, multi_level_bad, 2, BUFFER_OVERRUN_U5, no_bucket, ERROR, [Call,Unknown value from: __infer_taint_source,Assignment,Return,Assignment,Call,ArrayDeclaration,Parameter: i,ArrayAccess: Offset: [1, +oo] Size: 10 by call to `multi_level_sink_bad` ] +codetoanalyze/cpp/quandaryBO/tainted_index.cpp, multi_level_bad, 2, TAINTED_BUFFER_ACCESS, no_bucket, ERROR, [Return from __infer_taint_source with tainted data return*,Return from multi_level_source_bad,Call to multi_level_sink_bad with tainted index 0,Call to __array_access with tainted index 0,-----------,Call,Unknown value from: __infer_taint_source,Assignment,Return,Assignment,Call,ArrayDeclaration,Parameter: i,ArrayAccess: Offset: [1, +oo] Size: 10 by call to `multi_level_sink_bad` ] diff --git a/infer/tests/codetoanalyze/cpp/quandaryBO/multitest.make b/infer/tests/codetoanalyze/cpp/quandaryBO/multitest.make new file mode 100644 index 000000000..4c7168457 --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/quandaryBO/multitest.make @@ -0,0 +1,16 @@ +# Copyright (c) 2016-present, Facebook, Inc. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +TESTS_DIR = ../../.. + +ANALYZER = checkers +# see explanations in cpp/errors/Makefile for the custom isystem +CLANG_OPTIONS = -x c++ -std=c++11 -nostdinc++ -isystem$(ROOT_DIR) -isystem$(CLANG_INCLUDES)/c++/v1/ -c + +INFERPRINT_OPTIONS = --issues-tests + +SOURCES = $(wildcard *.cpp) + +include $(TESTS_DIR)/clang.make diff --git a/infer/tests/infer.make b/infer/tests/infer.make index bdc787758..2e2f24f37 100644 --- a/infer/tests/infer.make +++ b/infer/tests/infer.make @@ -28,11 +28,11 @@ print: issues.exp.test$(TEST_SUFFIX) .PHONY: test test: issues.exp.test$(TEST_SUFFIX) $(QUIET)cd $(TESTS_DIR) && \ - $(call check_no_diff,$(TEST_REL_DIR)/issues.exp,$(TEST_REL_DIR)/issues.exp.test$(TEST_SUFFIX)) + $(call check_no_diff,$(TEST_REL_DIR)/issues.exp$(TEST_RESULT_SUFFIX),$(TEST_REL_DIR)/issues.exp.test$(TEST_SUFFIX)) .PHONY: print replace: issues.exp.test$(TEST_SUFFIX) - cp $< issues.exp + cp $< issues.exp$(TEST_RESULT_SUFFIX) .PHONY: clean clean: