From 262a121cf6662a8ff83fd7da147c590a67b6cb59 Mon Sep 17 00:00:00 2001 From: Sam Blackshear Date: Sun, 21 Aug 2016 14:02:38 -0700 Subject: [PATCH] handle casts Reviewed By: jberdine Differential Revision: D3742480 fbshipit-source-id: 97b6b44 --- infer/src/quandary/TaintAnalysis.ml | 35 +++++++++++++++++++++-------- infer/src/unit/TaintTests.ml | 8 +++++++ infer/src/unit/analyzerTester.ml | 5 +++++ 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/infer/src/quandary/TaintAnalysis.ml b/infer/src/quandary/TaintAnalysis.ml index ab5a102ac..3958f5cd0 100644 --- a/infer/src/quandary/TaintAnalysis.ml +++ b/infer/src/quandary/TaintAnalysis.ml @@ -107,6 +107,15 @@ module Make (TraceDomain : Trace.S) = struct let access_tree = TaintDomain.add_node lhs_access_path rhs_node astate.Domain.access_tree in { astate with Domain.access_tree; } + let analyze_id_assignment lhs_id rhs_exp rhs_typ ({ Domain.id_map; } as astate) = + let f_resolve_id = resolve_id id_map in + match AccessPath.of_exp rhs_exp rhs_typ ~f_resolve_id with + | Some rhs_access_path -> + let id_map' = IdMapDomain.add lhs_id rhs_access_path id_map in + { astate with Domain.id_map = id_map'; } + | None -> + astate + let add_source source ret_id ret_typ access_tree = let trace = TraceDomain.of_source source in let id_ap = AccessPath.Exact (AccessPath.of_id ret_id ret_typ) in @@ -137,15 +146,8 @@ module Make (TraceDomain : Trace.S) = struct let exec_instr ({ Domain.id_map; } as astate) proc_data _ instr = let f_resolve_id = resolve_id id_map in match instr with - | Sil.Letderef (lhs_id, rhs_exp, rhs_typ, _loc) -> - begin - match AccessPath.of_exp rhs_exp rhs_typ ~f_resolve_id with - | Some rhs_access_path -> - let id_map' = IdMapDomain.add lhs_id rhs_access_path id_map in - { astate with Domain.id_map = id_map'; } - | None -> - astate - end + | Sil.Letderef (lhs_id, rhs_exp, rhs_typ, _) -> + analyze_id_assignment lhs_id rhs_exp rhs_typ astate | Sil.Set (lhs_exp, lhs_typ, rhs_exp, loc) -> let lhs_access_path = match AccessPath.of_exp lhs_exp lhs_typ ~f_resolve_id with @@ -175,6 +177,21 @@ module Make (TraceDomain : Trace.S) = struct | _ -> astate' end + | Sil.Call ([ret_id], Const (Cfun callee_pname), args, loc, _) + when Builtin.is_registered callee_pname -> + if Procname.equal callee_pname ModelBuiltins.__cast + then + match args with + | (cast_target, cast_typ) :: _ -> + analyze_id_assignment ret_id cast_target cast_typ astate + | _ -> + failwithf + "Unexpected cast %a in procedure %a at line %a" + (Sil.pp_instr pe_text) instr + Procname.pp (Cfg.Procdesc.get_proc_name (proc_data.ProcData.pdesc)) + Location.pp loc + else + astate | Sil.Call (ret_ids, Const (Cfun callee_pname), actuals, callee_loc, _) -> let call_site = CallSite.make callee_pname callee_loc in diff --git a/infer/src/unit/TaintTests.ml b/infer/src/unit/TaintTests.ml index 2e49514cc..763cbe3c5 100644 --- a/infer/src/unit/TaintTests.ml +++ b/infer/src/unit/TaintTests.ml @@ -259,5 +259,13 @@ let tests = invariant "{ base_id$0.f => (SOURCE -> ?), ret_id$0 => (SOURCE -> ?), &var.f => (SOURCE -> SINK) }"; ]; + "source -> sink via cast", + [ + assign_to_source "ret_id"; + cast_id_to_id "cast_id" Typ.Tvoid "ret_id"; + call_sink "cast_id"; + invariant "{ ret_id$0 => (SOURCE -> SINK) }"; + ]; + ] |> TestInterpreter.create_tests ~pp_opt:pp_sparse [] in "taint_test_suite">:::test_list diff --git a/infer/src/unit/analyzerTester.ml b/infer/src/unit/analyzerTester.ml index b2468b486..3b6e946b6 100644 --- a/infer/src/unit/analyzerTester.ml +++ b/infer/src/unit/analyzerTester.ml @@ -121,6 +121,11 @@ module StructuredSil = struct let rhs_exp = Exp.Var (ident_of_str rhs_id) in make_set ~rhs_typ ~lhs_exp ~rhs_exp + let cast_id_to_id lhs cast_typ rhs = + let lhs_id = ident_of_str lhs in + let rhs_id = Exp.Var (ident_of_str rhs) in + make_call ~procname:ModelBuiltins.__cast [lhs_id] [rhs_id, cast_typ] + let var_assign_exp ~rhs_typ lhs rhs_exp = let lhs_exp = var_of_str lhs in make_set ~rhs_typ ~lhs_exp ~rhs_exp