From 63f8a3e7096a8f64e82157cf06c66419dd8b620a Mon Sep 17 00:00:00 2001 From: Sam Blackshear Date: Mon, 14 Mar 2016 09:03:31 -0700 Subject: [PATCH] refactoring facebook-specific and open-source taint lists to fix open-source tests Reviewed By: jvillard Differential Revision: D3041560 fb-gh-sync-id: 549b571 shipit-source-id: 549b571 --- infer/src/backend/symExec.ml | 2 +- infer/src/backend/tabulation.ml | 2 +- infer/src/backend/taint.ml | 178 ++++++++++++++++++++ infer/src/{opensource => backend}/taint.mli | 4 +- infer/src/checkers/patternMatch.ml | 9 + infer/src/checkers/patternMatch.mli | 9 + infer/src/opensource/fbTaint.ml | 12 ++ infer/src/opensource/fbTaint.mli | 14 ++ infer/src/opensource/taint.ml | 18 -- 9 files changed, 226 insertions(+), 22 deletions(-) create mode 100644 infer/src/backend/taint.ml rename infer/src/{opensource => backend}/taint.mli (88%) create mode 100644 infer/src/opensource/fbTaint.ml create mode 100644 infer/src/opensource/fbTaint.mli delete mode 100644 infer/src/opensource/taint.ml diff --git a/infer/src/backend/symExec.ml b/infer/src/backend/symExec.ml index f5137405b..8279fc544 100644 --- a/infer/src/backend/symExec.ml +++ b/infer/src/backend/symExec.ml @@ -879,7 +879,7 @@ let add_constraints_on_retval pdesc prop ret_exp typ callee_pname callee_loc = (* bind return id to the abducted value pointed to by the pvar we introduced *) bind_exp_to_abducted_val ret_exp abducted_ret_pv prop in let prop'' = add_ret_non_null ret_exp typ prop' in - if !Config.taint_analysis && Taint.returns_secret callee_pname then + if !Config.taint_analysis && Taint.returns_tainted callee_pname then add_tainted_post ret_exp { Sil.taint_source = callee_pname; taint_kind = Unknown } prop'' else prop'' else add_ret_non_null ret_exp typ prop diff --git a/infer/src/backend/tabulation.ml b/infer/src/backend/tabulation.ml index bea98ebcc..4e4e628f4 100644 --- a/infer/src/backend/tabulation.ml +++ b/infer/src/backend/tabulation.ml @@ -821,7 +821,7 @@ let mk_posts ret_ids prop callee_pname posts = IList.filter (fun (prop, _) -> not (returns_null prop)) posts else posts in let mk_retval_tainted posts = - if Taint.returns_secret callee_pname then + if Taint.returns_tainted callee_pname then let taint_retval (prop, path) = let prop_normal = Prop.normalize prop in let prop' = diff --git a/infer/src/backend/taint.ml b/infer/src/backend/taint.ml new file mode 100644 index 000000000..51d41c8c2 --- /dev/null +++ b/infer/src/backend/taint.ml @@ -0,0 +1,178 @@ +(* + * Copyright (c) 2016 - 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. + *) + +module L = Logging + +open PatternMatch + +(* list of sources that return a tainted value *) +let sources = [ + (* for testing only *) + { + classname = "com.facebook.infer.models.InferTaint"; + method_name = "inferSecretSource"; + ret_type = "java.lang.Object"; + params = []; + is_static = true; + language = Config.Java; + }; + { + classname = "com.facebook.infer.models.InferTaint"; + method_name = "inferSecretSourceUndefined"; + ret_type = "java.lang.Object"; + params = []; + is_static = true; + language = Config.Java + }; + (* actual specs *) + { + classname = "com.facebook.katana.urimap.Fb4aUriIntentMapper"; + method_name = "getIntentForUri"; + ret_type = "android.content.Intent"; + params = ["android.content.Context"; "java.lang.String"]; + is_static = false; + language = Config.Java + }; + { + classname = "com.facebook.prefs.shared.FbSharedPreferences"; + method_name = "getString"; + ret_type = "java.lang.String"; + params = ["com.facebook.prefs.shared.PrefKey"; "java.lang.String"]; + is_static = false; + language = Config.Java + }; + { + classname = "android.content.SharedPreferences"; + method_name = "getString"; + ret_type = "java.lang.String"; + params = ["java.lang.String"; "java.lang.String"]; + is_static = false; + language = Config.Java + }; +] @ FbTaint.sources + +(* list of (sensitive sinks, zero-indexed numbers of parameters that should not be tainted). note: + index 0 means "the first non-this/self argument"; we currently don't have a way to say "this/self + should not be tainted" with this form of specification *) +let sinks = [ + (* for testing only *) + ({ + classname = "com.facebook.infer.models.InferTaint"; + method_name = "inferSensitiveSink"; + ret_type = "void"; + params = ["java.lang.Object"]; + is_static = true; + language = Config.Java + }, [0]); + ({ + classname = "com.facebook.infer.models.InferTaint"; + method_name = "inferSensitiveSinkUndefined"; + ret_type = "void"; + params = ["java.lang.Object"]; + is_static = true; + language = Config.Java + }, [0]); + (* actual specs *) + ({ + classname = "android.util.Log"; + method_name = "d"; + ret_type = "int"; + params = ["java.lang.String"; "java.lang.String"]; + is_static = true; + language = Config.Java + }, [0;1]); + + (* ==== iOS for testing only ==== *) + ({ + classname = "ExampleViewController"; + method_name = "loadURL:trackingCodes:"; + ret_type = "void"; + params = []; + is_static = false; + language = Config.C_CPP + }, [1]); (* it's instance method *) +] @ FbTaint.sinks + +let functions_with_tainted_params = [ + (* ==== iOS for testing only ==== *) + ({ + classname = "ExampleDelegate"; + method_name = "application:openURL:sourceApplication:annotation:"; + ret_type = "BOOL"; + params = []; + is_static = false; (* it's instance method *) + language = Config.C_CPP + }, [2]); + + (* actual specs *) + ({ (* This method is a source in iOS as it get as parameter + a non trusted URL (openURL). The method the passes + it around and this URL may arrive unsanitized to + loadURL:trackingCodes: of FBWebViewController + which uses the URL. *) + classname = "AppDelegate"; + method_name = "application:openURL:sourceApplication:annotation:"; + ret_type = "BOOL"; + params = []; + is_static = false; (* it's instance method *) + language = Config.C_CPP + }, [2]); +] @ FbTaint.functions_with_tainted_params + +(* turn string specificiation of Java method into a procname *) +let java_method_to_procname java_method = + Procname.mangled_java + (Procname.split_classname java_method.classname) + (Some (Procname.split_classname java_method.ret_type)) + java_method.method_name + (IList.map Procname.split_classname java_method.params) + (if java_method.is_static then Procname.Static else Procname.Non_Static) + +(* turn string specificiation of an objc method into a procname *) +let objc_method_to_procname objc_method = + let method_kind = Procname.objc_method_kind_of_bool (not objc_method.is_static) in + let mangled = Procname.mangled_of_objc_method_kind method_kind in + Procname.mangled_c_method objc_method.classname objc_method.method_name mangled + +let method_str_to_pname method_str = + match method_str.language with + | Config.C_CPP -> objc_method_to_procname method_str + | Config.Java -> java_method_to_procname method_str + +let sources = + IList.map method_str_to_pname sources + +let mk_pname_param_num methods = + IList.map + (fun (mname, param_num) -> method_str_to_pname mname, param_num) + methods + +let sinks = + mk_pname_param_num sinks + +let func_with_tainted_params = + mk_pname_param_num functions_with_tainted_params + +(** returns true if [callee_pname] returns a tainted value *) +let returns_tainted callee_pname = + IList.exists (fun pname -> Procname.equal pname callee_pname) sources + +let find_callee methods callee_pname = + try + snd (IList.find (fun (pname, _) -> Procname.equal pname callee_pname) methods) + with Not_found -> [] + +(** returns list of zero-indexed argument numbers of [callee_pname] that may be tainted *) +let accepts_sensitive_params callee_pname = + find_callee sinks callee_pname + +(** returns list of zero-indexed parameter numbers of [callee_pname] that should be + considered tainted during symbolic execution *) +let tainted_params callee_pname = + find_callee func_with_tainted_params callee_pname diff --git a/infer/src/opensource/taint.mli b/infer/src/backend/taint.mli similarity index 88% rename from infer/src/opensource/taint.mli rename to infer/src/backend/taint.mli index 5b3c89f9d..ba88e1a6d 100644 --- a/infer/src/opensource/taint.mli +++ b/infer/src/backend/taint.mli @@ -1,5 +1,5 @@ (* - * Copyright (c) 2013 - present Facebook, Inc. + * Copyright (c) 2016 - present Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD style license found in the @@ -8,7 +8,7 @@ *) (** returns true if [callee_pname] returns a tainted value *) -val returns_secret : Procname.t -> bool +val returns_tainted : Procname.t -> bool (** returns list of zero-indexed argument numbers of [callee_pname] that may be tainted *) val accepts_sensitive_params : Procname.t -> int list diff --git a/infer/src/checkers/patternMatch.ml b/infer/src/checkers/patternMatch.ml index aacfb6090..b4d539dc7 100644 --- a/infer/src/checkers/patternMatch.ml +++ b/infer/src/checkers/patternMatch.ml @@ -12,6 +12,15 @@ module L = Logging module F = Format +type method_str = { + classname : string; + method_name : string; + ret_type : string; + params : string list; + is_static : bool; + language : Config.language +} + let object_name = Mangled.from_string "java.lang.Object" let type_is_object = function diff --git a/infer/src/checkers/patternMatch.mli b/infer/src/checkers/patternMatch.mli index f563024cd..3ec90341f 100644 --- a/infer/src/checkers/patternMatch.mli +++ b/infer/src/checkers/patternMatch.mli @@ -9,6 +9,15 @@ (** Module for Pattern matching. *) +type method_str = { + classname : string; + method_name : string; + ret_type : string; + params : string list; + is_static : bool; + language : Config.language +} + (** Returns the signature of a field access (class name, field name, field type name) *) val get_java_field_access_signature : Sil.instr -> (string * string * string) option diff --git a/infer/src/opensource/fbTaint.ml b/infer/src/opensource/fbTaint.ml new file mode 100644 index 000000000..de06c2edc --- /dev/null +++ b/infer/src/opensource/fbTaint.ml @@ -0,0 +1,12 @@ +(* + * Copyright (c) 2016 - 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. + *) + +let sources = [] +let sinks = [] +let functions_with_tainted_params = [] diff --git a/infer/src/opensource/fbTaint.mli b/infer/src/opensource/fbTaint.mli new file mode 100644 index 000000000..61a503971 --- /dev/null +++ b/infer/src/opensource/fbTaint.mli @@ -0,0 +1,14 @@ +(* + * Copyright (c) 2016 - 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. + *) + +val sources : PatternMatch.method_str list + +val sinks : (PatternMatch.method_str * int list) list + +val functions_with_tainted_params : (PatternMatch.method_str * int list) list diff --git a/infer/src/opensource/taint.ml b/infer/src/opensource/taint.ml deleted file mode 100644 index 4d6c2dac9..000000000 --- a/infer/src/opensource/taint.ml +++ /dev/null @@ -1,18 +0,0 @@ -(* - * Copyright (c) 2013 - 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. - *) - -(** returns true if [callee_pname] returns a tainted value *) -let returns_secret callee_pname = false - -(** returns list of zero-indexed argument numbers of [callee_pname] that may be tainted *) -let accepts_sensitive_params callee_pname = [] - -(** returns list of zero-indexed parameter numbers of [callee_pname] that should be - considered tainted during symbolic execution *) -let tainted_params callee_pname = []