[quandary] move sanitizer specifications from TaintSpec -> Trace

Reviewed By: jeremydubreil

Differential Revision: D6301650

fbshipit-source-id: aae10a3
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent d392ed12a8
commit 758048078b

@ -0,0 +1,27 @@
(*
* Copyright (c) 2017 - 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.
*)
open! IStd
module F = Format
module type S = sig
type t [@@deriving compare]
val get : Typ.Procname.t -> t option
val pp : F.formatter -> t -> unit
end
module Dummy = struct
type t = unit [@@deriving compare]
let get _ = None
let pp _ _ = ()
end

@ -0,0 +1,23 @@
(*
* Copyright (c) 2017 - 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.
*)
open! IStd
module F = Format
(** Sanitizers for filtering traces in taint analysis *)
module type S = sig
type t [@@deriving compare]
val get : Typ.Procname.t -> t option
(** Get the sanitizer that should be applied to the return value of given procedure, if any *)
val pp : F.formatter -> t -> unit
end
module Dummy : S

@ -40,6 +40,7 @@ end
module Make (TraceElem : TraceElem.S) = struct module Make (TraceElem : TraceElem.S) = struct
include Trace.Make (struct include Trace.Make (struct
module Source = Source.Dummy module Source = Source.Dummy
module Sanitizer = Sanitizer.Dummy
module Sink = MakeSink (TraceElem) module Sink = MakeSink (TraceElem)
let get_report _ _ = Some IssueType.do_not_report let get_report _ _ = Some IssueType.do_not_report

@ -16,6 +16,8 @@ module type Spec = sig
module Sink : Sink.S module Sink : Sink.S
module Sanitizer : Sanitizer.S
val get_report : Source.t -> Sink.t -> IssueType.t option val get_report : Source.t -> Sink.t -> IssueType.t option
end end

@ -16,6 +16,8 @@ module type Spec = sig
module Sink : Sink.S module Sink : Sink.S
module Sanitizer : Sanitizer.S
val get_report : Source.t -> Sink.t -> IssueType.t option val get_report : Source.t -> Sink.t -> IssueType.t option
(** return Some(issue) if the source and sink match, None otherwise *) (** return Some(issue) if the source and sink match, None otherwise *)
end end

@ -98,23 +98,5 @@ include TaintAnalysis.Make (struct
| _ -> | _ ->
None None
let external_sanitizers =
List.map
~f:(fun {QuandaryConfig.Sanitizer.procedure} ->
QualifiedCppName.Match.of_fuzzy_qual_names [procedure])
(QuandaryConfig.Sanitizer.of_json Config.quandary_sanitizers)
let get_sanitizer pname =
let qualified_pname = Typ.Procname.get_qualifiers pname in
List.find_map
~f:(fun qualifiers ->
if QualifiedCppName.Match.match_qualifiers qualifiers qualified_pname then
Some TaintSpec.Return
else None)
external_sanitizers
let is_taintable_type _ = true let is_taintable_type _ = true
end) end)

@ -297,9 +297,32 @@ end
module CppSink = Sink.Make (SinkKind) module CppSink = Sink.Make (SinkKind)
module CppSanitizer = struct
type t = All [@@deriving compare]
let external_sanitizers =
List.map
~f:(fun {QuandaryConfig.Sanitizer.procedure} ->
QualifiedCppName.Match.of_fuzzy_qual_names [procedure])
(QuandaryConfig.Sanitizer.of_json Config.quandary_sanitizers)
let get pname =
let qualified_pname = Typ.Procname.get_qualifiers pname in
List.find_map
~f:(fun qualifiers ->
if QualifiedCppName.Match.match_qualifiers qualifiers qualified_pname then Some All
else None)
external_sanitizers
let pp fmt = function All -> F.fprintf fmt "All"
end
include Trace.Make (struct include Trace.Make (struct
module Source = CppSource module Source = CppSource
module Sink = CppSink module Sink = CppSink
module Sanitizer = CppSanitizer
let get_report source sink = let get_report source sink =
(* TODO: make this accept structs/objects too, but not primitive types or enumes *) (* TODO: make this accept structs/objects too, but not primitive types or enumes *)

@ -79,28 +79,6 @@ include TaintAnalysis.Make (struct
let get_model _ _ _ _ _ = None let get_model _ _ _ _ _ = None
let external_sanitizers =
List.map
~f:(fun {QuandaryConfig.Sanitizer.procedure} -> Str.regexp procedure)
(QuandaryConfig.Sanitizer.of_json Config.quandary_sanitizers)
let get_sanitizer = function
| Typ.Procname.Java java_pname ->
let procedure_string =
Printf.sprintf "%s.%s"
(Typ.Procname.java_get_class_name java_pname)
(Typ.Procname.java_get_method java_pname)
in
List.find_map
~f:(fun procedure_regex ->
if Str.string_match procedure_regex procedure_string 0 then Some TaintSpec.Return
else None)
external_sanitizers
| _ ->
None
let is_taintable_type typ = let is_taintable_type typ =
match typ.Typ.desc with match typ.Typ.desc with
| Typ.Tptr ({desc= Tstruct JavaClass typename}, _) | Tstruct JavaClass typename -> ( | Typ.Tptr ({desc= Tstruct JavaClass typename}, _) | Tstruct JavaClass typename -> (

@ -349,9 +349,37 @@ end
module JavaSink = Sink.Make (SinkKind) module JavaSink = Sink.Make (SinkKind)
module JavaSanitizer = struct
type t = All [@@deriving compare]
let external_sanitizers =
List.map
~f:(fun {QuandaryConfig.Sanitizer.procedure} -> Str.regexp procedure)
(QuandaryConfig.Sanitizer.of_json Config.quandary_sanitizers)
let get = function
| Typ.Procname.Java java_pname ->
let procedure_string =
Printf.sprintf "%s.%s"
(Typ.Procname.java_get_class_name java_pname)
(Typ.Procname.java_get_method java_pname)
in
List.find_map
~f:(fun procedure_regex ->
if Str.string_match procedure_regex procedure_string 0 then Some All else None)
external_sanitizers
| _ ->
None
let pp fmt = function All -> F.fprintf fmt "All"
end
include Trace.Make (struct include Trace.Make (struct
module Source = JavaSource module Source = JavaSource
module Sink = JavaSink module Sink = JavaSink
module Sanitizer = JavaSanitizer
let get_report source sink = let get_report source sink =
match (Source.kind source, Sink.kind sink) with match (Source.kind source, Sink.kind sink) with

@ -627,13 +627,8 @@ module Make (TaintSpecification : TaintSpec.S) = struct
| None -> | None ->
astate_with_summary astate_with_summary
| Some ret_base -> | Some ret_base ->
match TaintSpecification.get_sanitizer callee_pname with match TraceDomain.Sanitizer.get callee_pname with
| Some Return -> | Some _ ->
(* clear the trace associated with the return value. ideally, we would
associate a kind with the sanitizer and only clear the trace when its
kind matches the source. but this gets complicated to do properly with
footprint sources, since we don't know their kind. so do the simple
thing for now. *)
TaintDomain.BaseMap.remove ret_base astate_with_summary TaintDomain.BaseMap.remove ret_base astate_with_summary
| None -> | None ->
astate_with_summary astate_with_summary

@ -19,8 +19,6 @@ type action =
(** Propagate taint from all non-receiver actuals to the receiver actual *) (** Propagate taint from all non-receiver actuals to the receiver actual *)
| Propagate_to_return (** Propagate taint from all actuals to the return value *) | Propagate_to_return (** Propagate taint from all actuals to the return value *)
type sanitizer = Return (** a sanitizer that removes taint from its return value *)
module type S = sig module type S = sig
module Trace : Trace.S module Trace : Trace.S
@ -39,9 +37,6 @@ module type S = sig
val is_taintable_type : Typ.t -> bool val is_taintable_type : Typ.t -> bool
(** return true if the given typ can be tainted *) (** return true if the given typ can be tainted *)
val get_sanitizer : Typ.Procname.t -> sanitizer option
(** get the sanitizer associated with the given type, if any *)
val to_summary_access_tree : AccessTree.t -> QuandarySummary.AccessTree.t val to_summary_access_tree : AccessTree.t -> QuandarySummary.AccessTree.t
val of_summary_access_tree : QuandarySummary.AccessTree.t -> AccessTree.t val of_summary_access_tree : QuandarySummary.AccessTree.t -> AccessTree.t

@ -39,6 +39,8 @@ module MockTrace = Trace.Make (struct
end) end)
module Sanitizer = Sanitizer.Dummy
let get_report _ _ = None let get_report _ _ = None
end) end)
@ -55,8 +57,6 @@ module MockTaintAnalysis = TaintAnalysis.Make (struct
let is_taintable_type _ = true let is_taintable_type _ = true
let get_model _ _ _ _ _ = None let get_model _ _ _ _ _ = None
let get_sanitizer _ = None
end) end)
module TestInterpreter = module TestInterpreter =

@ -79,6 +79,7 @@ end
module MockTrace = Trace.Make (struct module MockTrace = Trace.Make (struct
module Source = MockSource module Source = MockSource
module Sink = MockSink module Sink = MockSink
module Sanitizer = Sanitizer.Dummy
let get_report source sink = let get_report source sink =
if [%compare.equal : MockTraceElem.t] (Source.kind source) (Sink.kind sink) then if [%compare.equal : MockTraceElem.t] (Source.kind source) (Sink.kind sink) then
@ -139,4 +140,3 @@ let tests =
"append" >:: append_ "append" >:: append_
in in
"trace_domain_suite" >::: [get_reports; append] "trace_domain_suite" >::: [get_reports; append]

Loading…
Cancel
Save