(* * 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. *) open! IStd module F = Format module L = Logging include TaintAnalysis.Make(struct module Trace = ClangTrace module AccessTree = AccessTree.Make(Trace) let to_summary_access_tree tree = QuandarySummary.AccessTree.Clang tree let of_summary_access_tree = function | QuandarySummary.AccessTree.Clang tree -> tree | _ -> assert false let handle_unknown_call pname ret_typ_opt actuals _ = let handle_generic_unknown ret_typ_opt actuals = match ret_typ_opt, List.rev actuals with | Some _, _ -> (* propagate taint from actuals to return value *) [TaintSpec.Propagate_to_return] | None, [] -> [] | None, _ when Typ.Procname.is_constructor pname -> (* "this" is always the first arg of a constructor; propagate taint there *) [TaintSpec.Propagate_to_receiver] | None, HilExp.AccessPath ((Var.ProgramVar pvar, { desc=Typ.Tptr (_, Typ.Pk_pointer) }), []) :: _ when Pvar.is_frontend_tmp pvar -> (* no return value, but the frontend has introduced a dummy return variable and will assign the return value to this variable. So propagate taint to the dummy return variable *) let actual_index = List.length actuals - 1 in [TaintSpec.Propagate_to_actual actual_index] | None, _ -> (* no return value; propagate taint from actuals to receiver *) [TaintSpec.Propagate_to_receiver] in (* if we have a specific model for a procedure, use that. otherwise, use the generic heuristics for dealing with unknown code *) match Typ.Procname.get_method pname with | "operator+=" | "operator-=" | "operator*=" | "operator/=" | "operator%=" | "operator<<=" | "operator>>=" | "operator&=" | "operator^=" | "operator|=" -> [TaintSpec.Propagate_to_receiver; TaintSpec.Propagate_to_return] | "memcpy" | "memmove" | "strcpy" | "strncpy" -> [TaintSpec.Propagate_to_receiver; TaintSpec.Propagate_to_return] | "sprintf" -> [TaintSpec.Propagate_to_receiver] | other -> L.d_strln ("generic unknown " ^ other); handle_generic_unknown ret_typ_opt actuals let is_taintable_type _ = true end)