From 9d844b707a430169cc76b4be10b0757ad49ffd4f Mon Sep 17 00:00:00 2001 From: Daiva Naudziuniene Date: Mon, 12 Mar 2018 10:50:56 -0700 Subject: [PATCH] Use after free false postives due to missing operator++ of hash map iterator Reviewed By: mbouaziz Differential Revision: D6899153 fbshipit-source-id: dff74d8 --- infer/tests/codetoanalyze/cpp/errors/Makefile | 1 + .../tests/codetoanalyze/cpp/errors/issues.exp | 3 + .../cpp/errors/use_after_free/foreach_map.cpp | 74 +++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 infer/tests/codetoanalyze/cpp/errors/use_after_free/foreach_map.cpp diff --git a/infer/tests/codetoanalyze/cpp/errors/Makefile b/infer/tests/codetoanalyze/cpp/errors/Makefile index 347cce854..59eb7fa2c 100644 --- a/infer/tests/codetoanalyze/cpp/errors/Makefile +++ b/infer/tests/codetoanalyze/cpp/errors/Makefile @@ -67,6 +67,7 @@ SOURCES = \ $(wildcard subtyping/*.cpp) \ $(wildcard templates/*.cpp) \ $(wildcard types/*.cpp) \ + $(wildcard use_after_free/*.cpp) \ $(wildcard vector/*.cpp) \ include $(TESTS_DIR)/clang.make diff --git a/infer/tests/codetoanalyze/cpp/errors/issues.exp b/infer/tests/codetoanalyze/cpp/errors/issues.exp index c955bbb69..f78a3b945 100644 --- a/infer/tests/codetoanalyze/cpp/errors/issues.exp +++ b/infer/tests/codetoanalyze/cpp/errors/issues.exp @@ -197,6 +197,9 @@ codetoanalyze/cpp/errors/types/typeid_expr.cpp, person_typeid_name, 8, DIVIDE_BY codetoanalyze/cpp/errors/types/typeid_expr.cpp, template_type_id_person, 2, MEMORY_LEAK, ERROR, [start of procedure template_type_id_person(),start of procedure Person,return from a call to Person_Person,Skipping template_typeid(): function or method not found] codetoanalyze/cpp/errors/types/typeid_expr.cpp, template_type_id_person, 5, DIVIDE_BY_ZERO, ERROR, [start of procedure template_type_id_person(),start of procedure Person,return from a call to Person_Person,Condition is false] codetoanalyze/cpp/errors/types/typeid_expr.cpp, template_typeid, 2, MEMORY_LEAK, ERROR, [start of procedure template_typeid(),start of procedure Person,return from a call to Person_Person,start of procedure Person,return from a call to Person_Person,start of procedure ~Person,start of procedure __infer_inner_destructor_~Person,return from a call to Person___infer_inner_destructor_~Person,return from a call to Person_~Person] +codetoanalyze/cpp/errors/use_after_free/foreach_map.cpp, use_after_free::Basic_test_double_delete_bad, 3, USE_AFTER_FREE, ERROR, [start of procedure test_double_delete_bad,Skipping Y: function or method not found] +codetoanalyze/cpp/errors/use_after_free/foreach_map.cpp, use_after_free::Basic_test_for_map_delete_ok_FP, 2, USE_AFTER_FREE, ERROR, [start of procedure test_for_map_delete_ok_FP,Condition is true,Skipping operator*: function or method not found,Condition is true,Skipping operator*: function or method not found,Condition is true,Skipping operator*: function or method not found] +codetoanalyze/cpp/errors/use_after_free/foreach_map.cpp, use_after_free::Basic_test_for_umap_delete_ok_FP, 2, USE_AFTER_FREE, ERROR, [start of procedure test_for_umap_delete_ok_FP,Condition is true,Skipping operator*: function or method not found,Condition is true,Skipping operator*: function or method not found,Condition is true,Skipping operator*: function or method not found] codetoanalyze/cpp/errors/vector/access_field_later.cpp, getIntPtr, 2, EMPTY_VECTOR_ACCESS, ERROR, [start of procedure getIntPtr()] codetoanalyze/cpp/errors/vector/access_field_later.cpp, getWithCopy, 2, EMPTY_VECTOR_ACCESS, ERROR, [start of procedure getWithCopy()] codetoanalyze/cpp/errors/vector/access_field_later.cpp, getWithCopyPtr, 2, EMPTY_VECTOR_ACCESS, ERROR, [start of procedure getWithCopyPtr()] diff --git a/infer/tests/codetoanalyze/cpp/errors/use_after_free/foreach_map.cpp b/infer/tests/codetoanalyze/cpp/errors/use_after_free/foreach_map.cpp new file mode 100644 index 000000000..17712a085 --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/errors/use_after_free/foreach_map.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2018 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include +#include +#include +#include + +struct Y { + int f; + ~Y(){}; +}; + +namespace use_after_free { +class Basic { + public: + Basic() {} + + std::unordered_map umap_ys; + std::map map_ys; + std::vector> pairs_ys; + std::vector ys; + + void test_delete_ok() { + Y* p = new Y(); + delete p; + } + + void test_double_delete_bad() { + Y* p = new Y(); + delete p; + delete p; // error + } + + void test_for_vector_delete_ok() { + for (auto& y : ys) { + delete y; + } + } + + void test_for_pairs_delete_ok() { + for (auto& y : pairs_ys) { + delete y.second; + } + } + + // TODO: missing model of std::__hash_map_iterator,void*>*>>_operator++ + void test_for_map_delete_ok_FP() { + for (auto& y : map_ys) { + delete y.second; // error + } + } + + // TODO: missing model of std::__hash_map_iterator,void*>*>>_operator++ + void test_for_umap_delete_ok_FP() { + for (auto& y : umap_ys) { + delete y.second; // error + } + } + + void test_for_umap_delete_break_ok() { + for (auto& y : umap_ys) { + delete y.second; + break; + } + } +}; +} // namespace use_after_free