From f821d8948ff84de9f2d28aeeadb12046ae9ac23b Mon Sep 17 00:00:00 2001 From: Sam Blackshear Date: Tue, 22 Aug 2017 12:20:38 -0700 Subject: [PATCH] [quandary] add memcpy, memset, and similar as sinks Reviewed By: jeremydubreil Differential Revision: D5676226 fbshipit-source-id: 52a20d1 --- infer/src/quandary/ClangTaintAnalysis.ml | 3 ++ infer/src/quandary/ClangTrace.ml | 6 +++ .../codetoanalyze/cpp/quandary/arrays.cpp | 43 +++++++++++++++++++ .../codetoanalyze/cpp/quandary/issues.exp | 9 ++++ 4 files changed, 61 insertions(+) diff --git a/infer/src/quandary/ClangTaintAnalysis.ml b/infer/src/quandary/ClangTaintAnalysis.ml index 7341099a1..ef189161d 100644 --- a/infer/src/quandary/ClangTaintAnalysis.ml +++ b/infer/src/quandary/ClangTaintAnalysis.ml @@ -65,6 +65,9 @@ include TaintAnalysis.Make (struct -> [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_opt actuals diff --git a/infer/src/quandary/ClangTrace.ml b/infer/src/quandary/ClangTrace.ml index 59eb8889f..83e028d5c 100644 --- a/infer/src/quandary/ClangTrace.ml +++ b/infer/src/quandary/ClangTrace.ml @@ -198,6 +198,12 @@ module SinkKind = struct -> taint_nth 0 ShellExec actuals | "brk" | "calloc" | "malloc" | "realloc" | "sbrk" -> taint_all Allocation actuals + | "strcpy" + -> (* warn if source array is tainted *) + taint_nth 1 BufferAccess actuals + | "memcpy" | "memmove" | "memset" | "strncpy" | "wmemcpy" | "wmemmove" + -> (* warn if count argument is tainted *) + taint_nth 2 BufferAccess actuals | _ -> get_external_sink pname actuals ) | Typ.Procname.Block _ diff --git a/infer/tests/codetoanalyze/cpp/quandary/arrays.cpp b/infer/tests/codetoanalyze/cpp/quandary/arrays.cpp index 0f54c4425..4cc574a0f 100644 --- a/infer/tests/codetoanalyze/cpp/quandary/arrays.cpp +++ b/infer/tests/codetoanalyze/cpp/quandary/arrays.cpp @@ -48,6 +48,49 @@ int stack_smash_bad() { return arr[0]; // could read from anywhere in the stack } +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]; } diff --git a/infer/tests/codetoanalyze/cpp/quandary/issues.exp b/infer/tests/codetoanalyze/cpp/quandary/issues.exp index 4bb406b51..8a5ef903a 100644 --- a/infer/tests/codetoanalyze/cpp/quandary/issues.exp +++ b/infer/tests/codetoanalyze/cpp/quandary/issues.exp @@ -9,9 +9,16 @@ codetoanalyze/cpp/quandary/arrays.cpp, arrays::array_sink1_bad, 2, QUANDARY_TAIN codetoanalyze/cpp/quandary/arrays.cpp, arrays::array_sink2_bad, 2, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __array_access] codetoanalyze/cpp/quandary/arrays.cpp, arrays::array_sink3_bad, 0, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __array_access] codetoanalyze/cpp/quandary/arrays.cpp, arrays::array_sink4_bad, 2, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __array_access] +codetoanalyze/cpp/quandary/arrays.cpp, arrays::memcpy_bad, 2, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to memcpy] +codetoanalyze/cpp/quandary/arrays.cpp, arrays::memmove_bad, 2, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to memmove] +codetoanalyze/cpp/quandary/arrays.cpp, arrays::memset_bad, 2, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to memset] codetoanalyze/cpp/quandary/arrays.cpp, arrays::stack_smash_bad, 2, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __set_array_length] codetoanalyze/cpp/quandary/arrays.cpp, arrays::std_array_sink_bad, 2, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to std::array_operator[]] codetoanalyze/cpp/quandary/arrays.cpp, arrays::std_string_sink_bad, 2, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to std::basic_string,std::allocator>_operator[]] +codetoanalyze/cpp/quandary/arrays.cpp, arrays::strcpy_bad, 2, QUANDARY_TAINT_ERROR, [Return from getenv,Call to strcpy] +codetoanalyze/cpp/quandary/arrays.cpp, arrays::strncpy_bad, 2, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to strncpy] +codetoanalyze/cpp/quandary/arrays.cpp, arrays::wmemcpy_bad, 2, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to wmemcpy] +codetoanalyze/cpp/quandary/arrays.cpp, arrays::wmemmove_bad, 2, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to wmemmove] codetoanalyze/cpp/quandary/basics.cpp, basics::Obj_endpoint, 1, QUANDARY_TAINT_ERROR, [Return from basics::Obj_endpoint,Call to basics::Obj_string_sink] codetoanalyze/cpp/quandary/basics.cpp, basics::Obj_endpoint, 2, QUANDARY_TAINT_ERROR, [Return from basics::Obj_endpoint,Call to __infer_taint_sink] codetoanalyze/cpp/quandary/basics.cpp, basics::object_source_sink_bad, 2, QUANDARY_TAINT_ERROR, [Return from basics::Obj_method_source,Call to basics::Obj_method_sink] @@ -81,7 +88,9 @@ codetoanalyze/cpp/quandary/strings.cpp, strings::replace1_bad, 2, QUANDARY_TAINT codetoanalyze/cpp/quandary/strings.cpp, strings::replace2_bad, 3, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink] codetoanalyze/cpp/quandary/strings.cpp, strings::sprintf1_bad, 4, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink] codetoanalyze/cpp/quandary/strings.cpp, strings::sprintf2_bad, 4, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink] +codetoanalyze/cpp/quandary/strings.cpp, strings::strcpy1_bad, 3, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to strcpy] codetoanalyze/cpp/quandary/strings.cpp, strings::strcpy1_bad, 4, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink] +codetoanalyze/cpp/quandary/strings.cpp, strings::strcpy2_bad, 3, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to strcpy] codetoanalyze/cpp/quandary/strings.cpp, strings::strcpy2_bad, 4, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink] codetoanalyze/cpp/quandary/strings.cpp, strings::strncpy_bad, 4, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink] codetoanalyze/cpp/quandary/strings.cpp, strings::swap_bad, 4, QUANDARY_TAINT_ERROR, [Return from __infer_taint_source,Call to __infer_taint_sink]